responsiblePerson.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448
  1. <template>
  2. <div>
  3. <div class="gva-search-box">
  4. <el-form ref="searchForm" :inline="true" :model="searchInfo">
  5. <el-form-item>
  6. <el-select v-model="searchInfo.searchKey" >
  7. <el-option
  8. v-for="item in searchOptions"
  9. :key="item.value"
  10. :label="item.label"
  11. :value="item.value"
  12. />
  13. </el-select>
  14. </el-form-item>
  15. <el-form-item>
  16. <el-input v-model="searchInfo.name" placeholder="请输入关键字"/>
  17. </el-form-item>
  18. <el-form-item>
  19. <el-button size="small" type="primary" icon="search" @click="onSubmit">搜索</el-button>
  20. </el-form-item>
  21. </el-form>
  22. </div>
  23. <div class="gva-btn-list">
  24. <el-button size="small" icon="refresh" @click="onReset">刷新</el-button>
  25. <el-button size="small" type="primary" icon="plus" @click="openDialog('addResponsiblePerson')">新增</el-button>
  26. <el-popover v-model="deleteVisible" placement="top" width="160">
  27. <p>确定要删除吗?</p>
  28. <div style="text-align: right; margin-top: 8px;">
  29. <el-button size="small" type="primary" link @click="deleteVisible = false">取消</el-button>
  30. <el-button size="small" type="primary" @click="onDelete">确定</el-button>
  31. </div>
  32. <template #reference>
  33. <el-button icon="delete" type="danger" size="small" :disabled="!apis.length" style="margin-left: 10px;" @click="deleteVisible = true">删除</el-button>
  34. </template>
  35. </el-popover>
  36. </div>
  37. <div class="gva-table-box">
  38. <el-table
  39. :data="tableData"
  40. @sort-change="sortChange"
  41. @selection-change="handleSelectionChange"
  42. >
  43. <el-table-column
  44. type="selection"
  45. width="55"
  46. />
  47. <el-table-column align="center" label="头像" min-width="100">
  48. <template #default="scope">
  49. <CustomPic style="margin-top:8px" :pic-src="scope.row.img" />
  50. </template>
  51. </el-table-column>
  52. <el-table-column align="left" label="姓名" min-width="150" prop="name" />
  53. <el-table-column align="left" label="昵称" min-width="150" prop="nickname" />
  54. <el-table-column align="left" label="部门名称" min-width="150" prop="department_name" />
  55. <el-table-column align="left" label="手机号码" min-width="150" prop="mobile_phone_number" />
  56. <el-table-column align="left" label="游戏数量" min-width="150" prop="game_counts" />
  57. <el-table-column align="left" label="备注" min-width="150" prop="remark" />
  58. <el-table-column align="center" label="状态" min-width="150" prop="state" >
  59. <template #default="scope">
  60. <el-button size="small"
  61. :type="scope.row.state == 2 ? 'danger' : 'success'">
  62. {{scope.row.state == 2? '禁用' : '启用'}}
  63. </el-button>
  64. </template>
  65. </el-table-column>
  66. <el-table-column align="left" label="创建时间" min-width="200" prop="createTime" sortable="custom" />
  67. <el-table-column align="left" fixed="right" label="操作" width="200">
  68. <template #default="scope">
  69. <el-button
  70. icon="edit"
  71. size="small"
  72. type="primary"
  73. link
  74. @click="editApiFunc(scope.row)"
  75. >编辑</el-button>
  76. <el-button
  77. icon="delete"
  78. size="small"
  79. type="primary"
  80. link
  81. @click="deleteApiFunc(scope.row)"
  82. >删除</el-button>
  83. </template>
  84. </el-table-column>
  85. </el-table>
  86. <div class="gva-pagination">
  87. <el-pagination
  88. :current-page="page"
  89. :page-size="pageSize"
  90. :page-sizes="[10, 30, 50, 100]"
  91. :total="total"
  92. layout="total, sizes, prev, pager, next, jumper"
  93. @current-change="handleCurrentChange"
  94. @size-change="handleSizeChange"
  95. />
  96. </div>
  97. </div>
  98. <el-dialog
  99. v-model="dialogFormVisible"
  100. custom-class="user-dialog"
  101. :before-close="closeDialog"
  102. :title="dialogTitle"
  103. :show-close="false"
  104. :close-on-press-escape="false"
  105. :close-on-click-modal="false"
  106. >
  107. <div style="height:60vh;overflow:auto;padding:0 12px;">
  108. <el-form ref="userForm" :rules="rules" :model="userInfo" label-width="80px">
  109. <el-form-item label="姓名" prop="name">
  110. <el-input v-model="userInfo.name" />
  111. </el-form-item>
  112. <el-form-item label="昵称" prop="nickname">
  113. <el-input v-model="userInfo.nickname" />
  114. </el-form-item>
  115. <el-form-item label="部门" prop="department_name">
  116. <el-input v-model="userInfo.department_name" />
  117. </el-form-item>
  118. <el-form-item label="手机号码" prop="mobile_phone_number">
  119. <el-input v-model="userInfo.mobile_phone_number" />
  120. </el-form-item>
  121. <el-form-item label="备注" prop="remark">
  122. <el-input v-model="userInfo.remark" />
  123. </el-form-item>
  124. <el-form-item label="状态" prop="state">
  125. <el-radio-group v-model="userInfo.state" class="ml-4">
  126. <el-radio :label="1" size="large">开启</el-radio>
  127. <el-radio :label="2" size="large">关闭</el-radio>
  128. </el-radio-group>
  129. </el-form-item>
  130. <el-form-item label="头像" label-width="80px">
  131. <div style="display:inline-block" @click="openHeaderChange">
  132. <img v-if="userInfo.img" class="header-img-box" :src="(userInfo.img && userInfo.img.slice(0, 4) !== 'http')?path+userInfo.img:userInfo.img">
  133. <div v-else class="header-img-box">从媒体库选择</div>
  134. </div>
  135. </el-form-item>
  136. </el-form>
  137. </div>
  138. <template #footer>
  139. <div class="dialog-footer">
  140. <el-button size="small" @click="closeDialog">取 消</el-button>
  141. <el-button size="small" type="primary" @click="enterDialog">确 定</el-button>
  142. </div>
  143. </template>
  144. </el-dialog>
  145. <ChooseImg ref="chooseImg" :target="userInfo" :target-key="`img`" />
  146. </div>
  147. </template>
  148. <script>
  149. export default {
  150. // name: 'User',
  151. // state: 0,
  152. }
  153. </script>
  154. <script setup>
  155. import {
  156. getApiById,
  157. getApiList,
  158. createApi,
  159. updateApi,
  160. deleteApi,
  161. deleteApisByIds
  162. } from '@/api/responsiblePerson'
  163. import { toSQLLine } from '@/utils/stringFun'
  164. import CustomPic from '@/components/customPic/customIndex.vue'
  165. import ChooseImg from '@/components/chooseImg/index.vue'
  166. import warningBar from '@/components/warningBar/warningBar.vue'
  167. import { nextTick, ref, watch } from 'vue'
  168. import { ElMessage, ElMessageBox } from 'element-plus'
  169. import User from '../superAdmin/user/user.vue'
  170. const form = ref({
  171. })
  172. const searchOptions = ref([
  173. {
  174. value: 'name',
  175. label: '姓名',
  176. },
  177. ])
  178. const type = ref('')
  179. const page = ref(1)
  180. const total = ref(0)
  181. const pageSize = ref(10)
  182. const tableData = ref([])
  183. const searchInfo = ref({
  184. searchKey:"name",
  185. })
  186. const onReset = () => {
  187. searchInfo.value = {}
  188. }
  189. // 搜索
  190. const onSubmit = () => {
  191. page.value = 1
  192. pageSize.value = 10
  193. getTableData()
  194. }
  195. // 分页
  196. const handleSizeChange = (val) => {
  197. pageSize.value = val
  198. getTableData()
  199. }
  200. const handleCurrentChange = (val) => {
  201. page.value = val
  202. getTableData()
  203. }
  204. // 排序
  205. const sortChange = ({ prop, order }) => {
  206. if (prop) {
  207. if (prop === 'ID') {
  208. prop = 'id'
  209. }
  210. searchInfo.value.orderKey = toSQLLine(prop)
  211. searchInfo.value.desc = order === 'descending'
  212. }
  213. getTableData()
  214. }
  215. // 查询
  216. const getTableData = async() => {
  217. const table = await getApiList({ page: page.value, pageSize: pageSize.value, ...searchInfo.value})
  218. if (table.code === 0) {
  219. tableData.value = table.data.list
  220. total.value = table.data.total
  221. page.value = table.data.page
  222. pageSize.value = table.data.pageSize
  223. }
  224. }
  225. getTableData()
  226. // 批量操作
  227. const handleSelectionChange = (val) => {
  228. apis.value = val
  229. }
  230. const apis = ref([])
  231. const deleteVisible = ref(false)
  232. const onDelete = async() => {
  233. const ids = apis.value.map(item => item.id)
  234. const res = await deleteApisByIds({ ids })
  235. if (res.code === 0) {
  236. ElMessage({
  237. type: 'success',
  238. message: res.msg
  239. })
  240. if (tableData.value.length === ids.length && page.value > 1) {
  241. page.value--
  242. }
  243. deleteVisible.value = false
  244. getTableData()
  245. }
  246. }
  247. // 弹窗相关
  248. const userInfo = ref({
  249. name: '',
  250. nickname: '',
  251. department_name: '',
  252. mobile_phone_number: '',
  253. remark: '',
  254. state: 0,
  255. img: '',
  256. })
  257. const path = ref(import.meta.env.VITE_BASE_API + '/')
  258. const userForm = ref(null)
  259. const initForm = () => {
  260. userForm.value.resetFields()
  261. userInfo.value = {
  262. name: '',
  263. nickname: '',
  264. department_name: '',
  265. mobile_phone_number: '',
  266. remark: '',
  267. state: 0,
  268. img: '',
  269. }
  270. }
  271. const dialogTitle = ref('新增Api')
  272. const dialogFormVisible = ref(false)
  273. const openDialog = (key) => {
  274. switch (key) {
  275. case 'addResponsiblePerson':
  276. dialogTitle.value = '新增'
  277. break
  278. case 'editResponsiblePerson':
  279. dialogTitle.value = '编辑'
  280. break
  281. default:
  282. break
  283. }
  284. type.value = key
  285. dialogFormVisible.value = true
  286. }
  287. const closeDialog = () => {
  288. initForm()
  289. dialogFormVisible.value = false
  290. userInfo.value.img = ''
  291. }
  292. const editApiFunc = async(row) => {
  293. const res = await getApiById({ id: row.id })
  294. userInfo.value = res.data.responsible_person
  295. openDialog('editResponsiblePerson')
  296. }
  297. const enterDialog = async() => {
  298. userForm.value.validate(async valid => {
  299. if (valid) {
  300. switch (type.value) {
  301. case 'addResponsiblePerson':
  302. {
  303. const res = await createApi(userInfo.value)
  304. if (res.code === 0) {
  305. ElMessage({
  306. type: 'success',
  307. message: '添加成功',
  308. showClose: true
  309. })
  310. }
  311. getTableData()
  312. closeDialog()
  313. }
  314. break
  315. case 'editResponsiblePerson':
  316. {
  317. const res = await updateApi(userInfo.value)
  318. if (res.code === 0) {
  319. ElMessage({
  320. type: 'success',
  321. message: '编辑成功',
  322. showClose: true
  323. })
  324. }
  325. getTableData()
  326. closeDialog()
  327. }
  328. break
  329. default:
  330. // eslint-disable-next-line no-lone-blocks
  331. {
  332. ElMessage({
  333. type: 'error',
  334. message: '未知操作',
  335. showClose: true
  336. })
  337. }
  338. break
  339. }
  340. }
  341. })
  342. }
  343. const chooseImg = ref(null)
  344. const openHeaderChange = () => {
  345. chooseImg.value.open()
  346. }
  347. const deleteApiFunc = async(row) => {
  348. ElMessageBox.confirm('此操作将永久删除此负责人, 是否继续?', '提示', {
  349. confirmButtonText: '确定',
  350. cancelButtonText: '取消',
  351. type: 'warning'
  352. })
  353. .then(async() => {
  354. const res = await deleteApi(row)
  355. if (res.code === 0) {
  356. ElMessage({
  357. type: 'success',
  358. message: '删除成功!'
  359. })
  360. if (tableData.value.length === 1 && page.value > 1) {
  361. page.value--
  362. }
  363. getTableData()
  364. }
  365. })
  366. }
  367. </script>
  368. <style lang="scss">
  369. .user-dialog {
  370. .header-img-box {
  371. width: 200px;
  372. height: 200px;
  373. border: 1px dashed #ccc;
  374. border-radius: 20px;
  375. text-align: center;
  376. line-height: 200px;
  377. cursor: pointer;
  378. }
  379. .avatar-uploader .el-upload:hover {
  380. border-color: #409eff;
  381. }
  382. .avatar-uploader-icon {
  383. border: 1px dashed #d9d9d9 !important;
  384. border-radius: 6px;
  385. font-size: 28px;
  386. color: #8c939d;
  387. width: 178px;
  388. height: 178px;
  389. line-height: 178px;
  390. text-align: center;
  391. }
  392. .avatar {
  393. width: 178px;
  394. height: 178px;
  395. display: block;
  396. }
  397. }
  398. .nickName{
  399. display: flex;
  400. justify-content: flex-start;
  401. align-items: center;
  402. }
  403. .pointer{
  404. cursor: pointer;
  405. font-size: 16px;
  406. margin-left: 2px;
  407. }
  408. </style>