BaseInfo.vue 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149
  1. <template>
  2. <div>
  3. <n-card
  4. :bordered="true"
  5. title="属性信息"
  6. class="proCard mt-2"
  7. size="small"
  8. :segmented="{ content: true }"
  9. >
  10. <template #header-extra>
  11. <n-space>
  12. <!-- <n-button
  13. strong
  14. secondary
  15. type="error"
  16. v-show="useUserStore.config.mode !== 'release'"
  17. @click="openCompatibilityTest"
  18. >档案拷贝
  19. </n-button> -->
  20. <n-button strong secondary type="success" @click="showModalRetrofit = true"
  21. >添加配装
  22. </n-button>
  23. <!-- <n-button strong secondary type="info" @click="openSetDanScoreModal">修改段位分</n-button>
  24. <n-button strong secondary type="info" @click="showModal">账号等级对照表</n-button>
  25. <n-button
  26. strong
  27. secondary
  28. type="success"
  29. v-show="!showModifyBase"
  30. @click="openUpdatePlayerBase"
  31. >修改属性
  32. </n-button>
  33. <n-button
  34. strong
  35. secondary
  36. type="info"
  37. v-show="showModifyBase"
  38. @click="showModifyBase = false"
  39. >预览属性
  40. </n-button>
  41. <n-button strong secondary type="success" @click="showModalGift = true"
  42. >赠送礼包</n-button
  43. >-->
  44. </n-space>
  45. </template>
  46. <n-descriptions
  47. label-placement="left"
  48. label-align="left"
  49. :column="4"
  50. size="large"
  51. v-show="!showModifyBase"
  52. >
  53. <n-descriptions-item>
  54. <template #label>玩家等级</template>
  55. <span class="default_text_value">{{ userInfo.userLevel }}</span>
  56. </n-descriptions-item>
  57. <n-descriptions-item label="玩家体力">
  58. <n-space>
  59. <span class="default_text_value">{{ userInfo.materials['16001'] }}</span>
  60. </n-space>
  61. </n-descriptions-item>
  62. <n-descriptions-item label="玩家精力">
  63. <n-space>
  64. <span class="default_text_value">{{ userInfo.materials['16001'] }}</span>
  65. </n-space>
  66. </n-descriptions-item>
  67. <n-descriptions-item label="玩家经验">
  68. <n-space>
  69. <span class="default_text_value">{{ userInfo.userExp }}</span>
  70. </n-space>
  71. </n-descriptions-item>
  72. <n-descriptions-item label="玩家金币">
  73. <n-space>
  74. <span class="default_text_value">{{ userInfo.materials['3001'] }}</span>
  75. </n-space>
  76. </n-descriptions-item>
  77. <n-descriptions-item label="玩家钻石">
  78. <n-space>
  79. <span class="default_text_value">{{ userInfo.materials['3002'] }}</span>
  80. </n-space>
  81. </n-descriptions-item>
  82. </n-descriptions>
  83. <!-- 修改属性 -->
  84. <n-form v-show="showModifyBase" ref="formRef" :model="formValue">
  85. <n-alert :show-icon="false">增加或减少玩家属性,默认填0表示不修改</n-alert>
  86. <n-row :gutter="24">
  87. <n-col :span="6">
  88. <n-form-item label="玩家经验" size="large">
  89. <n-input-number v-model:value="formValue.userExp" min="0" :max="99999999" />
  90. <template #feedback> 当前值 {{ userInfo.userExp }}</template>
  91. </n-form-item>
  92. </n-col>
  93. <n-col :span="6">
  94. <n-form-item label="天赋点" size="large">
  95. <n-input-number v-model:value="formValue.talentPoint" min="0" :max="99999999" />
  96. <template #feedback> 当前值 {{ userInfo.talentPoint }}</template>
  97. </n-form-item>
  98. </n-col>
  99. <n-col :span="6">
  100. <n-form-item label="玩家钻石" size="large">
  101. <n-input-number v-model:value="formValue.diamond" :max="99999999" :min="-99999999" />
  102. <template #feedback> 当前值 {{ userInfo.diamond }}</template>
  103. </n-form-item>
  104. </n-col>
  105. <n-col :span="6">
  106. <n-form-item label="玩家金币" size="large">
  107. <n-input-number v-model:value="formValue.coin" :max="99999999" :min="-99999999" />
  108. <template #feedback> 当前值 {{ userInfo.coin ?? 0 }}</template>
  109. </n-form-item>
  110. </n-col>
  111. <n-col :span="6">
  112. <n-form-item label="玩家体力" size="large">
  113. <n-input-number v-model:value="formValue.stamina" :max="99999999" :min="-99999999" />
  114. <template #feedback> 当前值 {{ userInfo.stamina }}</template>
  115. </n-form-item>
  116. </n-col>
  117. <n-col :span="6">
  118. <n-form-item label="玩家精力" size="large">
  119. <n-input-number v-model:value="formValue.energy" :max="99999999" :min="-99999999" />
  120. <template #feedback> 当前值 {{ userInfo.energy ?? 0 }}</template>
  121. </n-form-item>
  122. </n-col>
  123. </n-row>
  124. <n-form-item>
  125. <n-space>
  126. <n-button type="info" @click="handleValidateClick">保存修改</n-button>
  127. </n-space>
  128. </n-form-item>
  129. </n-form>
  130. </n-card>
  131. <n-card
  132. :bordered="true"
  133. title="账号信息"
  134. class="proCard mt-2"
  135. size="small"
  136. :segmented="{ content: true }"
  137. >
  138. <n-skeleton v-if="loading" text :repeat="6" />
  139. <template v-else>
  140. <n-descriptions label-placement="left" label-align="left" :column="4" size="large">
  141. <n-descriptions-item>
  142. <template #label>玩家ID</template>
  143. <span class="default_text_value">{{ userInfo.userId }}</span>
  144. </n-descriptions-item>
  145. <n-descriptions-item label="账号ID">
  146. <n-space>
  147. <span class="default_text_value">{{ userInfo.accId ?? '' }}</span>
  148. </n-space>
  149. </n-descriptions-item>
  150. <n-descriptions-item label="服务器">
  151. <n-space>
  152. <span class="default_text_value">{{ getServerName(attr.serverId) }}</span>
  153. </n-space>
  154. </n-descriptions-item>
  155. <n-descriptions-item label="openid">
  156. <n-space>
  157. <span class="default_text_value">{{ attr.openId }}</span>
  158. </n-space>
  159. </n-descriptions-item>
  160. <n-descriptions-item label="昵称">
  161. <n-space>
  162. <span class="default_text_value">{{ userInfo.nick }}</span>
  163. </n-space>
  164. </n-descriptions-item>
  165. <n-descriptions-item label="注册时间(当前服)">
  166. <n-space>
  167. <span class="default_text_value">{{ user.createtime }}</span>
  168. </n-space>
  169. </n-descriptions-item>
  170. <n-descriptions-item label="累计签到次数">
  171. <n-space>
  172. <span class="default_text_value">{{ attr.signinCount }}</span>
  173. </n-space>
  174. </n-descriptions-item>
  175. <n-descriptions-item label="最近登录">
  176. <n-space>
  177. <span class="default_text_value">{{ attr.lastlogintick ?? '' }}</span>
  178. </n-space>
  179. </n-descriptions-item>
  180. <n-descriptions-item label="最近登出">
  181. <n-space>
  182. <span class="default_text_value">{{ attr.lastlogouttick ?? '' }}</span>
  183. </n-space>
  184. </n-descriptions-item>
  185. <n-descriptions-item label="近90天登录">
  186. <n-space>
  187. <span class="default_text_value">{{ attr.loginCount ?? 0 }}次</span>
  188. </n-space>
  189. </n-descriptions-item>
  190. <n-descriptions-item label="近90天看广告">
  191. <n-space>
  192. <span class="default_text_value">{{ attr.advCount ?? '' }}次</span>
  193. </n-space>
  194. </n-descriptions-item>
  195. <n-descriptions-item label="近90天在线">
  196. <n-space>
  197. <span class="default_text_value">{{ attr.onlineDuration ?? '' }}</span>
  198. </n-space>
  199. </n-descriptions-item>
  200. </n-descriptions>
  201. </template>
  202. </n-card>
  203. <!-- <n-card
  204. :bordered="true"
  205. title="充值与消费 (消费数据统计时间从2022年9月1日开始)"
  206. class="proCard mt-2"
  207. size="small"
  208. :segmented="{ content: true }"
  209. >
  210. <n-skeleton v-if="loading" text :repeat="6" />
  211. <template v-else>
  212. <n-descriptions label-placement="left" label-align="left" :column="4" size="large">
  213. <n-descriptions-item>
  214. <template #label>累计充值次数</template>
  215. <span class="default_text_value">{{ order.rechargeCount }}</span>
  216. </n-descriptions-item>
  217. <n-descriptions-item label="累计充值钻石次数">
  218. <n-space>
  219. <span class="default_text_value">{{ order.rechargeDiamondCount }}</span>
  220. </n-space>
  221. </n-descriptions-item>
  222. <n-descriptions-item label="累计消费金币">
  223. <n-space>
  224. <span class="default_text_value">{{ order.consumptionCoinCount }}</span>
  225. </n-space>
  226. </n-descriptions-item>
  227. <n-descriptions-item label="累计消费钻石">
  228. <n-space>
  229. <span class="default_text_value">{{ order.consumptionDiamondCount }}</span>
  230. </n-space>
  231. </n-descriptions-item>
  232. <n-descriptions-item label="累计充值金额">
  233. <n-space>
  234. <span class="default_text_value">{{ order.rechargeAmount }} 元</span>
  235. </n-space>
  236. </n-descriptions-item>
  237. <n-descriptions-item label="首充时间">
  238. <n-space>
  239. <span class="default_text_value">{{ order.firstChargeAt }}</span>
  240. </n-space>
  241. </n-descriptions-item>
  242. <n-descriptions-item label="最近充值时间">
  243. <n-space>
  244. <span class="default_text_value">{{ order.lastChargeAt }}</span>
  245. </n-space>
  246. </n-descriptions-item>
  247. </n-descriptions>
  248. </template>
  249. </n-card>-->
  250. <!-- <n-card
  251. :bordered="true"
  252. title="玩家操作"
  253. class="proCard mt-2"
  254. size="small"
  255. :segmented="{ content: true }"
  256. >
  257. <n-skeleton v-if="loading" text :repeat="6" />
  258. <template v-else>
  259. <n-grid :cols="2">
  260. <n-form-item-gi label="全服封禁/解封">
  261. <n-switch v-model:value="userBan.ban" @update:value="handleBanUser">
  262. <template #checked> 已封禁 </template>
  263. <template #unchecked> 未封禁 </template>
  264. </n-switch>
  265. <span style="margin-left: 15px"> 封禁原因 </span>
  266. <n-input v-model:value="userBan.banReason" style="margin-left: 5px; width: 72%" />
  267. </n-form-item-gi>
  268. <n-form-item-gi label="当前服封禁/解封">
  269. <n-switch v-model:value="singleBan.ban" @update:value="handleSingleBanUser">
  270. <template #checked> 已封禁 </template>
  271. <template #unchecked> 未封禁 </template>
  272. </n-switch>
  273. <span style="margin-left: 15px"> 封禁原因 </span>
  274. <n-input v-model:value="singleBan.banReason" style="margin-left: 5px; width: 72%" />
  275. </n-form-item-gi>
  276. <n-form-item-gi label="支付关闭/开启">
  277. <n-switch v-model:value="paySwitch.pay" @update:value="PaymentSwitch">
  278. <template #checked> 已开启 </template>
  279. <template #unchecked> 已关闭 </template>
  280. </n-switch>
  281. <span style="margin-left: 15px"> 关闭原因 </span>
  282. <n-input v-model:value="paySwitch.banReason" style="margin-left: 5px; width: 72%" />
  283. </n-form-item-gi>
  284. <n-form-item-gi label="禁止聊天/解禁">
  285. <n-switch v-model:value="chatBan.ban" @update:value="handleChatBan">
  286. <template #checked> 已封禁 </template>
  287. <template #unchecked> 未封禁 </template>
  288. </n-switch>
  289. <span style="margin-left: 15px"> 解禁时间 </span>
  290. <n-date-picker
  291. style="margin-left: 5px"
  292. v-model:value="chatBan.deadline_time"
  293. type="datetime"
  294. clearable
  295. />
  296. <span style="margin-left: 15px"> 封禁原因 </span>
  297. <n-input v-model:value="chatBan.banReason" style="margin-left: 5px; width: 46%" />
  298. </n-form-item-gi>
  299. </n-grid>
  300. </template>
  301. </n-card>-->
  302. <!-- <n-card
  303. :bordered="true"
  304. title="支付操作"
  305. class="proCard mt-2"
  306. size="small"
  307. :segmented="{ content: true }">
  308. <n-skeleton v-if="loading" text :repeat="6" />
  309. <template v-else>
  310. <n-descriptions label-align="left" :column="2" size="large">
  311. <n-descriptions-item label="支付关闭/开启">
  312. <n-switch v-model:value="paySwitch.pay" @update:value="PaymentSwitch" />
  313. &nbsp;
  314. <span v-if="paySwitch.pay">已开启</span>
  315. <span v-else>已关闭</span>
  316. </n-descriptions-item>
  317. </n-descriptions>
  318. </template>
  319. </n-card> -->
  320. <n-modal
  321. v-model:show="showModalRetrofit"
  322. :show-icon="false"
  323. preset="dialog"
  324. title="添加配装"
  325. style="width: 620px"
  326. >
  327. <n-form
  328. :model="formParamsRetrofit"
  329. ref="formRefRetrofit"
  330. label-placement="left"
  331. :label-width="80"
  332. class="py-4"
  333. >
  334. <n-form-item label="选择模板" path="equipments">
  335. <n-select
  336. v-model:value="formParamsRetrofit.rid"
  337. placeholder="选择配装模板"
  338. :options="retrofitOptions"
  339. @update:value="handleMaterialTypeChange"
  340. />
  341. <template #feedback>
  342. <br />
  343. <p>
  344. <n-button size="small" secondary strong @click="addRetrofitGroup">
  345. 去添加配装模板
  346. <template #icon>
  347. <n-icon>
  348. <arrow-forward />
  349. </n-icon>
  350. </template>
  351. </n-button>
  352. </p>
  353. </template>
  354. </n-form-item>
  355. </n-form>
  356. <template #action>
  357. <n-space>
  358. <n-button @click="() => (showModalRetrofit = false)">取消</n-button>
  359. <n-button type="info" :loading="formBtnLoading" @click="retrofitConfirmForm"
  360. >确定
  361. </n-button>
  362. </n-space>
  363. </template>
  364. </n-modal>
  365. <basicModal @register="modalRegister" ref="modalRef" class="basicModal" @on-ok="okModal">
  366. <template #default>
  367. <Level />
  368. </template>
  369. </basicModal>
  370. <n-modal
  371. v-model:show="showModalOpenAccount"
  372. :mask-closable="false"
  373. preset="dialog"
  374. title="确认"
  375. :content="
  376. '开通账号登录后,将无法继续使用微信登录,开通成功后账号为:u' + userId + ', 密码为:123'
  377. "
  378. positive-text="确认"
  379. negative-text="取消"
  380. @positive-click="onPositiveClick"
  381. @negative-click="onNegativeClick"
  382. />
  383. <n-modal
  384. v-model:show="showModalUpdateNickname"
  385. :mask-closable="false"
  386. preset="dialog"
  387. title="修改玩家昵称"
  388. >
  389. <n-form
  390. :model="formParamsUpdateNickname"
  391. ref="formRefUpdateNickname"
  392. label-placement="left"
  393. :label-width="80"
  394. class="py-4"
  395. >
  396. <n-form-item label="昵称" path="nickname">
  397. <n-input v-model:value="formParamsUpdateNickname.nickname" />
  398. <template #feedback> 修改前请确认该账号已退出游戏,否则修改可能不会生效 </template>
  399. </n-form-item>
  400. </n-form>
  401. <template #action>
  402. <n-space>
  403. <n-button @click="() => (showModalUpdateNickname = false)">取消</n-button>
  404. <n-button
  405. type="info"
  406. :loading="formBtnUpdateNicknameLoading"
  407. @click="updateNicknameConfirmForm"
  408. >确定
  409. </n-button>
  410. </n-space>
  411. </template>
  412. </n-modal>
  413. <n-modal
  414. v-model:show="showModalCompatibilityTest"
  415. :show-icon="false"
  416. preset="dialog"
  417. title="档案拷贝"
  418. :style="{
  419. width: '720px',
  420. }"
  421. >
  422. <n-alert :show-icon="false"
  423. >将正式服玩家数据拷贝到测试服,操作过程中请勿登录该测试服账号,迁移成功后重启测试服生效!</n-alert
  424. >
  425. <n-form
  426. :model="formCompatibilityTestParams"
  427. ref="formRefCompatibilityTest"
  428. label-placement="left"
  429. :label-width="120"
  430. class="py-4"
  431. >
  432. <n-form-item label="服务器" path="service">
  433. <n-select
  434. placeholder="请选择服务器"
  435. :options="serviceList"
  436. v-model:value="formCompatibilityTestParams.service"
  437. />
  438. </n-form-item>
  439. <n-form-item label="正式服玩家ID" path="userId">
  440. <n-input-group>
  441. <n-input-number
  442. placeholder="请输入正式服玩家ID"
  443. style="width: 100%"
  444. v-model:value="formCompatibilityTestParams.produceUserId"
  445. />
  446. <n-button type="primary" @click="compatibilityTestVerify">验证账号</n-button>
  447. </n-input-group>
  448. </n-form-item>
  449. <n-form-item label="正式服所在服务器" path="serverName">
  450. <n-input
  451. placeholder=" "
  452. v-model:value="formCompatibilityTestParams.serverName"
  453. disabled
  454. />
  455. </n-form-item>
  456. <n-form-item label="正式服昵称" path="nickname">
  457. <n-input placeholder=" " v-model:value="formCompatibilityTestParams.nickname" disabled />
  458. </n-form-item>
  459. </n-form>
  460. <template #action>
  461. <n-space>
  462. <n-button @click="() => (showModalCompatibilityTest = false)">取消</n-button>
  463. <n-button
  464. type="info"
  465. :loading="formBtnCompatibilityTestLoading"
  466. @click="confirmCompatibilityTestForm"
  467. :disabled="!formCompatibilityTestParams.has"
  468. >拷贝玩家数据</n-button
  469. >
  470. </n-space>
  471. </template>
  472. </n-modal>
  473. <n-modal
  474. v-model:show="showModalGift"
  475. :show-icon="false"
  476. preset="dialog"
  477. title="赠送礼包"
  478. style="width: 620px"
  479. >
  480. <n-form
  481. :model="formParamsGift"
  482. ref="formRefGift"
  483. label-placement="left"
  484. :label-width="80"
  485. class="py-4"
  486. >
  487. <n-form-item label="礼包ID" path="giftId">
  488. <n-input-number placeholder="请输入礼包ID" v-model:value="formParamsGift.giftId" />
  489. </n-form-item>
  490. </n-form>
  491. <template #action>
  492. <n-space>
  493. <n-button @click="() => (showModalGift = false)">取消</n-button>
  494. <n-button type="info" :loading="formBtnLoading" @click="giftConfirmForm">确定 </n-button>
  495. </n-space>
  496. </template>
  497. </n-modal>
  498. <SetDanScore
  499. :showModal="showSetDanScoreModal"
  500. @updateShowModal="updateSetDanScoreModal"
  501. :userId="playerId"
  502. />
  503. </div>
  504. </template>
  505. <script lang="ts" setup>
  506. import { onMounted, reactive, ref, watch, computed } from 'vue';
  507. import { FormInst, SelectOption, useMessage } from 'naive-ui';
  508. import { baseForm, userInfoObj } from '@/views/account/accountList/userInfo';
  509. import { timestampToTime } from '@/utils/dateUtil';
  510. import {
  511. getPlayerAttr,
  512. // getSigninCount,
  513. getUserAccountInfo,
  514. openAccount,
  515. // orderStatistics,
  516. // playerAccountBan,
  517. updatePlayerBase,
  518. // playerSingleBan,
  519. UpdateNickname,
  520. CompatibilityTestVerify,
  521. CompatibilityTestMigrate,
  522. // playerPaymentSwitch,
  523. addGift,
  524. // playerChatBan,
  525. } from '@/api/account/list';
  526. import { useModal } from '@/components/Modal';
  527. import Level from '@/views/modal/Level.vue';
  528. import SetDanScore from './SetDanScore.vue';
  529. import { addPlayerRetrofit, RetrofitGroupOptions } from '@/api/echarts/rechargeList';
  530. import { ArrowForwardCircleOutline as ArrowForward } from '@vicons/ionicons5';
  531. import { useRouter } from 'vue-router';
  532. // import { useUserStoreWidthOut } from '@/store/modules/user';
  533. import { getServerName } from '@/utils/admin';
  534. // const useUserStore = useUserStoreWidthOut();
  535. const serviceList = [
  536. {
  537. label: '微信',
  538. value: 1,
  539. },
  540. {
  541. label: '抖音',
  542. value: 2,
  543. },
  544. {
  545. label: '美团',
  546. value: 3,
  547. },
  548. {
  549. label: '闲闲',
  550. value: 4,
  551. },
  552. ];
  553. const [modalRegister, { closeModal }] = useModal({
  554. title: '账号等级对照表',
  555. });
  556. async function okModal() {
  557. closeModal();
  558. }
  559. const singleBan = reactive({
  560. ban: false,
  561. banReason: '',
  562. });
  563. const chatBan = reactive({
  564. ban: false,
  565. deadline_time: 0,
  566. banReason: '',
  567. });
  568. const paySwitch = reactive({
  569. pay: false,
  570. banReason: '',
  571. });
  572. const userBan = reactive({
  573. ban: false,
  574. banReason: '',
  575. });
  576. const formParamsRetrofit = ref({
  577. rid: null,
  578. });
  579. interface Props {
  580. userId?: number | string;
  581. userInfo?: any;
  582. }
  583. const props = withDefaults(defineProps<Props>(), {
  584. userId: 0,
  585. userInfo: userInfoObj,
  586. });
  587. const formParamsGift = ref({
  588. giftId: 0,
  589. });
  590. const formRefCompatibilityTest = ref();
  591. const showModalCompatibilityTest = ref(false);
  592. const formBtnCompatibilityTestLoading = ref(false);
  593. const formCompatibilityTestParams = ref<any>({
  594. service: null,
  595. nickname: '',
  596. has: false,
  597. produceUserId: null,
  598. server: null,
  599. serverName: '',
  600. });
  601. const formRefUpdateNickname = ref();
  602. const showModalUpdateNickname = ref(false);
  603. const formBtnUpdateNicknameLoading = ref(false);
  604. const formParamsUpdateNickname = ref({
  605. nickname: '',
  606. });
  607. const playerId = computed(() => {
  608. return props.userId;
  609. });
  610. const router = useRouter();
  611. const retrofitOptions = ref([]);
  612. const formRefRetrofit: any = ref(null);
  613. const message = useMessage();
  614. const showModalOpenAccount = ref(false);
  615. const showModalRetrofit = ref(false);
  616. const showModalGift = ref(false);
  617. const formBtnLoading = ref(false);
  618. const loading = ref(false);
  619. const showModifyBase = ref(false);
  620. const formRef = ref<FormInst | null>(null);
  621. const formValue = ref<baseForm>({
  622. stamina: 0,
  623. energy: 0,
  624. userExp: 0,
  625. talentPoint: 0,
  626. coin: 0,
  627. diamond: 0,
  628. });
  629. const user = ref(
  630. reactive({
  631. openid: '',
  632. nickname: '',
  633. account: '',
  634. createtime: '',
  635. ban: '',
  636. })
  637. );
  638. const attr = ref(
  639. reactive({
  640. lastlogintick: '',
  641. lastlogouttick: '',
  642. signinCount: 0,
  643. advCount: 0,
  644. onlineDuration: '',
  645. serverId: 0,
  646. accId: 0,
  647. openId: '',
  648. loginCount: 0,
  649. })
  650. );
  651. /*const order = reactive({
  652. playerid: 0,
  653. orderPlatform: '',
  654. rechargeCount: 0,
  655. rechargeDiamondCount: 0,
  656. consumptionCoinCount: '',
  657. consumptionDiamondCount: '',
  658. firstChargeAt: '',
  659. lastChargeAt: '',
  660. rechargeAmount: 0,
  661. });*/
  662. /* function handleBanUser(info: boolean) {
  663. const banInfo = info ? 1 : 0;
  664. if (!info) {
  665. userBan.banReason = '';
  666. }
  667. playerAccountBan({
  668. ...{ playerid: Number(props.userId), ban: banInfo, reason: userBan.banReason },
  669. }).then((res) => {
  670. console.log('res:' + JSON.stringify(res));
  671. if (banInfo == 1) {
  672. userBan.ban = true;
  673. message.success('封禁成功,下次登录生效');
  674. } else {
  675. userBan.ban = false;
  676. message.success('解封成功');
  677. }
  678. });
  679. }
  680. function handleSingleBanUser(info: boolean) {
  681. const banInfo = info ? 1 : 0;
  682. if (!info) {
  683. singleBan.banReason = '';
  684. }
  685. playerSingleBan({
  686. ...{ playerid: Number(props.userId), ban: banInfo, reason: singleBan.banReason },
  687. }).then((res) => {
  688. console.log('res:' + JSON.stringify(res));
  689. if (banInfo == 1) {
  690. singleBan.ban = true;
  691. message.success('封禁成功,下次登录生效');
  692. } else {
  693. singleBan.ban = false;
  694. message.success('解封成功');
  695. }
  696. });
  697. }
  698. function handleChatBan(info: boolean) {
  699. const banInfo = info ? 1 : 0;
  700. if (!info) {
  701. chatBan.banReason = '';
  702. }
  703. if (info && chatBan.deadline_time < Date.now()) {
  704. chatBan.ban = false;
  705. chatBan.deadline_time = null;
  706. message.error('时间选择不正确');
  707. return;
  708. }
  709. playerChatBan({
  710. ...{
  711. playerid: Number(props.userId),
  712. ban: banInfo,
  713. deadline_time: chatBan.deadline_time / 1000,
  714. reason: chatBan.banReason,
  715. },
  716. }).then((res) => {
  717. console.log('res:' + JSON.stringify(res));
  718. if (banInfo == 1) {
  719. chatBan.ban = true;
  720. message.success('封禁成功,下次登录生效');
  721. } else {
  722. chatBan.ban = false;
  723. chatBan.deadline_time = null;
  724. message.success('解封成功');
  725. }
  726. });
  727. }
  728. function PaymentSwitch(info: boolean) {
  729. let switchInfo = info ? 1 : 0;
  730. if (!info) {
  731. paySwitch.banReason = '';
  732. }
  733. console.log(switchInfo);
  734. playerPaymentSwitch({
  735. ...{ playerid: Number(props.userId), switch: switchInfo, reason: paySwitch.banReason },
  736. }).then((res) => {
  737. console.log('res:' + JSON.stringify(res));
  738. if (switchInfo == 1) {
  739. paySwitch.pay = true;
  740. message.success('关闭成功,下次登录生效');
  741. } else {
  742. paySwitch.pay = false;
  743. message.success('开启成功');
  744. }
  745. });
  746. }*/
  747. // function openUpdatePlayerBase() {
  748. // formValue.value = {
  749. // stamina: 0,
  750. // energy: 0,
  751. // userExp: 0,
  752. // talentPoint: 0,
  753. // coin: 0,
  754. // diamond: 0,
  755. // };
  756. // showModifyBase.value = true;
  757. // }
  758. function handleValidateClick(e: MouseEvent) {
  759. e.preventDefault();
  760. formRef.value?.validate((errors) => {
  761. if (!errors) {
  762. console.log('formValue111:' + JSON.stringify(formValue.value));
  763. updatePlayerBase({ ...formValue.value, ...{ playerid: Number(props.userId) } }).then(
  764. (_res) => {
  765. console.log('_res:' + JSON.stringify(_res));
  766. message.success('已提交后台处理,添加成功后会推送系统消息,刷新玩家信息查看结果');
  767. }
  768. );
  769. } else {
  770. console.log('errors:' + errors);
  771. message.error('Invalid');
  772. }
  773. });
  774. }
  775. function loadBaseInfo() {
  776. new Promise((_resolve, _reject) => {
  777. getUserAccountInfo({ playerid: props.userId })
  778. .then((res) => {
  779. // 用户信息
  780. // user.openid = res.openid;
  781. // user.nickname = res.nickname;
  782. user.value.account = res.account;
  783. // user.createtime = res.createtime > 0 ? timestampToTime(res.createtime) : '';
  784. // user.ban = res.ban == 1 ? '禁用' : '正常';
  785. userBan.ban = res.ban == 1;
  786. userBan.banReason = userBan.ban ? res.banReason : '';
  787. singleBan.ban = res.singleBan == 1;
  788. singleBan.banReason = singleBan.ban ? res.singleBanReason : '';
  789. chatBan.ban = res.chatBan == 1;
  790. chatBan.banReason = chatBan.ban ? res.chatBanReason : '';
  791. chatBan.deadline_time =
  792. res.chatBanDeadlineTime * 1000 < Date.now() ? 0 : res.chatBanDeadlineTime * 1000;
  793. paySwitch.banReason = res.payOffReason;
  794. })
  795. .catch((error) => {
  796. message.error(error.toString());
  797. });
  798. });
  799. new Promise((_resolve, _reject) => {
  800. getPlayerAttr({ playerid: props.userId })
  801. .then((res) => {
  802. console.log('=======res:', res);
  803. // 属性
  804. attr.value.lastlogintick =
  805. res.lastlogintick > 0 ? timestampToTime(res.lastlogintick) : '';
  806. attr.value.lastlogouttick =
  807. res.lastlogouttick > 0 ? timestampToTime(res.lastlogouttick) : '';
  808. attr.value.advCount = res.advCount;
  809. attr.value.onlineDuration = res.onlineDuration;
  810. attr.value.accId = res.accId;
  811. attr.value.serverId = res.line;
  812. attr.value.openId = res.openId;
  813. user.value.nickname = res.nickName;
  814. user.value.createtime = res.create_time > 0 ? timestampToTime(res.create_time) : '';
  815. paySwitch.pay = res.paySwitch == 1;
  816. paySwitch.banReason = paySwitch.pay ? paySwitch.banReason : '';
  817. console.log('========attr:', attr.value);
  818. })
  819. .catch((error) => {
  820. // message.error(error.toString());
  821. console.log('error:' + error.toString());
  822. });
  823. });
  824. /*new Promise((_resolve, _reject) => {
  825. orderStatistics({ playerid: props.userId })
  826. .then((res) => {
  827. if (res.orderPlatform == 1) {
  828. order.orderPlatform = '安卓';
  829. } else {
  830. order.orderPlatform = '苹果';
  831. }
  832. order.rechargeCount = res.rechargeCount;
  833. order.rechargeDiamondCount = res.rechargeDiamondCount;
  834. order.rechargeAmount = res.rechargeAmount;
  835. order.firstChargeAt = res.firstChargeAt > 0 ? timestampToTime(res.firstChargeAt) : '';
  836. order.lastChargeAt = res.lastChargeAt > 0 ? timestampToTime(res.lastChargeAt) : '';
  837. order.consumptionCoinCount = UtilsTool.unitConversion(res.consumptionCoinCount);
  838. order.consumptionDiamondCount = UtilsTool.unitConversion(res.consumptionDiamondCount);
  839. })
  840. .catch((error) => {
  841. // message.error(error.toString());
  842. console.log('error:' + error.toString());
  843. });
  844. });*/
  845. /*new Promise((_resolve, _reject) => {
  846. getSigninCount({ playerid: props.userId })
  847. .then((res) => {
  848. attr.signinCount = res.signinCount;
  849. attr.loginCount = res.loginCount;
  850. })
  851. .catch((e: Error) => {
  852. // message.error(e.message ?? '操作失败');
  853. console.log('error:' + e.message);
  854. });
  855. });*/
  856. }
  857. watch(props, (_newVal, _oldVal) => {
  858. loadBaseInfo();
  859. });
  860. onMounted(async () => {
  861. if (props.userId < 1) {
  862. console.log('传入用户信息不正确,props.userId:', props.userId);
  863. return;
  864. }
  865. loadBaseInfo();
  866. getRetrofitOptions();
  867. });
  868. function getRetrofitOptions() {
  869. new Promise((_resolve, _reject) => {
  870. RetrofitGroupOptions({})
  871. .then((res) => {
  872. retrofitOptions.value = res;
  873. })
  874. .catch((error) => {
  875. // message.error(error.toString());
  876. console.log('error:' + error.toString());
  877. });
  878. });
  879. }
  880. function handleMaterialTypeChange(value: string, _option: SelectOption) {
  881. console.log('value' + value);
  882. }
  883. function retrofitConfirmForm(e) {
  884. e.preventDefault();
  885. formRefRetrofit.value.validate((errors) => {
  886. if (!errors) {
  887. // console.log('formParamsRetrofit:' + JSON.stringify(formParamsRetrofit));
  888. if (formParamsRetrofit.value.rid === null) {
  889. message.error('请先选择一个配装');
  890. return;
  891. }
  892. addPlayerRetrofit({ id: formParamsRetrofit.value.rid, userId: props.userId })
  893. .then((_res) => {
  894. console.log('_res:' + JSON.stringify(_res));
  895. message.success('已提交后台处理,添加成功后会推送系统消息,刷新玩家信息查看结果');
  896. })
  897. .catch((e: Error) => {
  898. message.error(e.message ?? '操作失败');
  899. });
  900. setTimeout(() => {
  901. showModalRetrofit.value = false;
  902. // reloadTable();
  903. });
  904. } else {
  905. message.error('请填写完整信息');
  906. }
  907. formBtnLoading.value = false;
  908. });
  909. }
  910. // function openUpdateNickname() {
  911. // showModalUpdateNickname.value = true;
  912. // formParamsUpdateNickname.value.nickname = user.nickname;
  913. // }
  914. function updateNicknameConfirmForm(e) {
  915. e.preventDefault();
  916. formRefUpdateNickname.value.validate((errors) => {
  917. if (!errors) {
  918. console.log('formParamsUpdateNickname:' + JSON.stringify(formParamsUpdateNickname));
  919. if (formParamsUpdateNickname.value.nickname === '') {
  920. message.error('请输入昵称');
  921. return;
  922. }
  923. UpdateNickname({ nickname: formParamsUpdateNickname.value.nickname, userId: props.userId })
  924. .then((_res) => {
  925. console.log('_res:' + JSON.stringify(_res));
  926. user.value.nickname = formParamsUpdateNickname.value.nickname;
  927. message.success('修改成功');
  928. })
  929. .catch((e: Error) => {
  930. message.error(e.message ?? '操作失败');
  931. });
  932. setTimeout(() => {
  933. showModalUpdateNickname.value = false;
  934. // reloadTable();
  935. });
  936. } else {
  937. message.error('请填写完整信息');
  938. }
  939. formBtnUpdateNicknameLoading.value = false;
  940. });
  941. }
  942. function addRetrofitGroup() {
  943. router.push({
  944. name: 'retrofit-list',
  945. params: {},
  946. });
  947. }
  948. function onPositiveClick() {
  949. showModalOpenAccount.value = false;
  950. openAccount({
  951. ...{ userId: props.userId },
  952. })
  953. .then((res) => {
  954. console.log(res);
  955. message.success('开通成功');
  956. loadBaseInfo();
  957. })
  958. .catch((err) => {
  959. console.log(err);
  960. message.error(err);
  961. });
  962. }
  963. function onNegativeClick() {
  964. showModalOpenAccount.value = false;
  965. }
  966. // function openCompatibilityTest() {
  967. // showModalCompatibilityTest.value = true;
  968. // formCompatibilityTestParams.value.nickname = null;
  969. // formCompatibilityTestParams.value.server = null;
  970. // formCompatibilityTestParams.value.has = false;
  971. // formCompatibilityTestParams.value.serverName = '';
  972. // }
  973. function compatibilityTestVerify() {
  974. if (
  975. formCompatibilityTestParams.value.produceUserId === null ||
  976. formCompatibilityTestParams.value.produceUserId < 1
  977. ) {
  978. message.error('请输入正式服玩家ID');
  979. return;
  980. }
  981. console.log(formCompatibilityTestParams);
  982. CompatibilityTestVerify(formCompatibilityTestParams.value)
  983. .then((res) => {
  984. formCompatibilityTestParams.value.nickname = res.nickname;
  985. formCompatibilityTestParams.value.server = res.server;
  986. formCompatibilityTestParams.value.has = res.has;
  987. formCompatibilityTestParams.value.serverName = getServerName(
  988. formCompatibilityTestParams.value.server
  989. );
  990. console.log('_res:' + JSON.stringify(res));
  991. })
  992. .catch((error) => {
  993. message.error(error.message);
  994. });
  995. }
  996. function confirmCompatibilityTestForm(e) {
  997. e.preventDefault();
  998. formRefCompatibilityTest.value.validate((errors) => {
  999. if (!errors) {
  1000. console.log('formParamsCompatibilityTest:' + JSON.stringify(formCompatibilityTestParams));
  1001. if (formCompatibilityTestParams.value.produceUserId < 1) {
  1002. message.error('请输入正式服玩家ID');
  1003. return;
  1004. }
  1005. CompatibilityTestMigrate({
  1006. produceUserId: formCompatibilityTestParams.value.produceUserId,
  1007. userId: props.userId,
  1008. service: formCompatibilityTestParams.value.service,
  1009. })
  1010. .then((_res) => {
  1011. console.log('_res:' + JSON.stringify(_res));
  1012. message.success('数据迁移成功,请重启服务器!');
  1013. setTimeout(() => {
  1014. showModalCompatibilityTest.value = false;
  1015. // reloadTable();
  1016. });
  1017. })
  1018. .catch((e: Error) => {
  1019. message.error(e.message ?? '操作失败');
  1020. });
  1021. } else {
  1022. message.error('请填写完整信息');
  1023. }
  1024. formBtnCompatibilityTestLoading.value = false;
  1025. });
  1026. }
  1027. const showSetDanScoreModal = ref(false);
  1028. // function openSetDanScoreModal() {
  1029. // showSetDanScoreModal.value = true;
  1030. // }
  1031. function updateSetDanScoreModal(value) {
  1032. showSetDanScoreModal.value = value;
  1033. }
  1034. function giftConfirmForm(e) {
  1035. e.preventDefault();
  1036. addGift({
  1037. ...{ player_id: Number(props.userId), gift_id: formParamsGift.value.giftId },
  1038. })
  1039. .then((_res) => {
  1040. console.log('_res:' + JSON.stringify(_res));
  1041. message.success('已提交后台处理,添加成功后会推送系统消息');
  1042. })
  1043. .catch((e: Error) => {
  1044. message.error(e.message ?? '操作失败');
  1045. });
  1046. setTimeout(() => {
  1047. showModalGift.value = false;
  1048. });
  1049. }
  1050. </script>
  1051. <style lang="less" scoped>
  1052. .default_text_value {
  1053. color: var(--n-tab-text-color-active);
  1054. }
  1055. </style>