appAdmin.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. <template>
  2. <div class="layout-container">
  3. <!-- 菜单栏 -->
  4. <From :form-items="dynamicFormItems" @formSubmitted="handleFormSubmitted" @formReset="handleFormReset"
  5. is_add_button="新增" @addForm="edit" />
  6. <!-- 表格 -->
  7. <div class="layout-container">
  8. <Table @getTableData="changeTableData" v-model:page="page" ref="table" :data="tableData"
  9. @selection-change="handleSelectionChange">
  10. <el-table-column prop="appId" label="应用ID" width="140" />
  11. <el-table-column prop="appName" label="应用名称" />
  12. <el-table-column prop="appKey" label="应用秘钥" >
  13. <template #default="scope">
  14. <label>{{scope.row.showKey?scope.row.appKey: "******"}}</label>
  15. <span style="margin-left: 15px">
  16. <el-icon v-if="scope.row.showKey" @click="()=>{scope.row.showKey = !scope.row.showKey}"><View /></el-icon>
  17. <el-icon v-if="!scope.row.showKey" @click="()=>{scope.row.showKey = !scope.row.showKey}"><Hide /></el-icon>
  18. </span>
  19. <span style="margin-left: 5px">
  20. <el-icon v-copy="scope.row.appKey" ><CopyDocument /></el-icon>
  21. </span>
  22. </template>
  23. </el-table-column>
  24. <el-table-column prop="channelName" label="广告渠道名称" width="150" />
  25. <el-table-column prop="networkAppName" label="关联渠道应用" width="150" />
  26. <el-table-column prop="nickName" label="所属用户" />
  27. <el-table-column prop="appType" label="应用类型" width="100" >
  28. <template #default="scope">
  29. {{getDictionaryName("app_type",scope.row.appType)}}
  30. </template>
  31. </el-table-column>
  32. <el-table-column prop="apkUrl" label="下载链接" >
  33. <template #default="scope">
  34. <a :href="scope.row.apkUrl" target="_blank">{{scope.row.appName}}.apk</a>
  35. </template>
  36. </el-table-column>
  37. <el-table-column prop="qrCode" label="二维码" >
  38. <template #default="scope">
  39. <el-image style="width: 100px; height: 100px" :src="scope.row.qrCode" fit="fill" :preview-src-list="[scope.row.qrCode]" />
  40. </template>
  41. </el-table-column>
  42. <el-table-column prop="updateTips" label="更新提示" />
  43. <el-table-column prop="enabled" label="是否启用" >
  44. <template #default="scope">
  45. {{getDictionaryName("enabled",scope.row.enabled)}}
  46. </template>
  47. </el-table-column>
  48. <el-table-column label="操作" width="150" fixed="right">
  49. <template #default="scope">
  50. <div class="button">
  51. <el-button class="button-item" type="primary" style="margin-bottom: 5px" @click="edit(scope.row)">
  52. 编辑
  53. </el-button>
  54. <el-popconfirm placement="left" title="确认删除该数据?" @confirm="removeAgency(scope.row)">
  55. <template #reference>
  56. <el-button class="button-item" style="margin-bottom: 5px" type="warning">删除</el-button>
  57. </template>
  58. </el-popconfirm>
  59. </div>
  60. </template>
  61. </el-table-column>
  62. </Table>
  63. </div>
  64. <!-- 操作弹窗 -->
  65. <Layer :layer="layer" @confirm="submit(ruleForm)" @close="layer.show = false">
  66. <el-form :model="formEdit" :rules="rules" ref="ruleForm" label-width="120px" style="margin-right: 30px">
  67. <el-form-item label="请求秘钥:" required prop="apiKey">
  68. <el-input v-model="formEdit.apiKey" type="number" placeholder="请输入" clearable />
  69. </el-form-item>
  70. <el-form-item label="请求密令:" required prop="apiSecret">
  71. <el-input v-model="formEdit.apiSecret" placeholder="请输入" clearable />
  72. </el-form-item>
  73. <el-form-item label="渠道ID:" required prop="channelId">
  74. <el-input v-model="formEdit.channelId" placeholder="请输入" clearable />
  75. </el-form-item>
  76. <el-form-item label="渠道名称:" required prop="channelName">
  77. <el-input v-model="formEdit.channelName" placeholder="请输入" clearable />
  78. </el-form-item>
  79. <el-form-item label="渠道账号:" required prop="channelAccount">
  80. <el-input v-model="formEdit.channelAccount" placeholder="请输入" clearable />
  81. </el-form-item>
  82. <el-form-item label="渠道密码:" required prop="channelPwd">
  83. <el-input v-model="formEdit.channelPwd" placeholder="请输入" clearable />
  84. </el-form-item>
  85. <el-form-item label="渠道状态:" required prop="channelStatus">
  86. <el-input v-model="formEdit.channelStatus" placeholder="请输入" clearable />
  87. </el-form-item>
  88. <el-form-item label="登录类型:" required prop="loginType">
  89. <el-input v-model="formEdit.loginType" placeholder="请输入" clearable />
  90. </el-form-item>
  91. <el-form-item label="备注:" required prop="remark">
  92. <el-input v-model="formEdit.remark" placeholder="请输入" clearable />
  93. </el-form-item>
  94. </el-form>
  95. </Layer>
  96. </div>
  97. </template>
  98. <script setup>
  99. import { onBeforeMount, ref, reactive } from "vue";
  100. import { ElMessage } from "element-plus";
  101. import { useStore } from "vuex";
  102. import { useGetDictList } from "@/hooks/useGetDictList.js";
  103. import { channelAddOne, channelDeleteOne, channelUpdateOne, appList,} from "@/api/formworkErection.js";
  104. import From from "@/components/from/index.vue";
  105. import Table from "@/components/table/index.vue";
  106. import Layer from "@/components/layer/index.vue";
  107. import { CopyDocument, Hide, View} from "@element-plus/icons-vue";
  108. import vCopy from '@/directive/copy'
  109. const store = useStore();
  110. const { dictData, loadDictData, getOptions, getDictionaryName } = useGetDictList();
  111. const form = ref(null);
  112. const tableData = ref([
  113. ]);
  114. // 分页参数, 供table使用
  115. const page = reactive({
  116. pageNum: 1,
  117. pageSize: 20,
  118. limit: 20,
  119. total: 0,
  120. });
  121. const formSearch = ref({
  122. channelId: null, // 渠道ID
  123. channelName: null, // 渠道名称
  124. channelAccount: "", // 渠道账号
  125. channelStatus: null, // 渠道状态
  126. loginType: null, // 登录类型
  127. limit: 20, // 当前页数量(查询量)
  128. page: 1, // 当前页码
  129. pageSizes: 20, // 总页数
  130. });
  131. const dynamicFormItems = ref([]);
  132. onBeforeMount(() => {
  133. settingData();
  134. getList();
  135. });
  136. // 获取缓存数据设置筛选数据
  137. const settingData = () => {
  138. loadDictData().then(() => {
  139. dynamicFormItems.value = [
  140. {
  141. label: "渠道ID",
  142. prop: "channelId",
  143. type: "input",
  144. },
  145. {
  146. label: "渠道名称",
  147. prop: "channelName",
  148. type: "input",
  149. },
  150. {
  151. label: "渠道账号",
  152. prop: "channelAccount",
  153. type: "input",
  154. },
  155. {
  156. label: "渠道状态",
  157. prop: "channelStatus",
  158. type: "select",
  159. options: [
  160. {
  161. label: "全部",
  162. value: null,
  163. },
  164. {
  165. label: "是",
  166. value: 0,
  167. },
  168. {
  169. label: "否",
  170. value: 1,
  171. },
  172. ],
  173. },
  174. {
  175. label: "登录类型",
  176. prop: "loginType",
  177. type: "select",
  178. options: [
  179. {
  180. label: "全部",
  181. value: null,
  182. },
  183. {
  184. label: "账号密码",
  185. value: 1,
  186. },
  187. {
  188. label: "微信",
  189. value: 2,
  190. },
  191. ],
  192. },
  193. // { label: '登录日期', prop: 'loginTime', type: 'daterange' },
  194. ];
  195. });
  196. };
  197. // 分页数据
  198. const getList = async () => {
  199. let res = await appList({ ...formSearch.value });
  200. tableData.value = res.data;
  201. page.total = res.pageMeta.total;
  202. };
  203. const changeTableData = () => {
  204. formSearch.value.pageNum = page.pageNum;
  205. formSearch.value.pageSize = page.pageSize;
  206. formSearch.value.limit = page.limit;
  207. // 分页切换
  208. getList();
  209. };
  210. // 搜索
  211. const handleFormSubmitted = (formData) => {
  212. // console.log("接收到子组件传递的数据", formData);
  213. formSearch.value.page = 1;
  214. formSearch.value.pageSizes = 20;
  215. formSearch.value.limit = 20;
  216. formSearch.value.channelId = formData.channelId;
  217. formSearch.value.channelName = formData.channelName;
  218. formSearch.value.channelAccount = formData.channelAccount;
  219. formSearch.value.channelStatus = formData.channelStatus;
  220. formSearch.value.loginType = formData.loginType;
  221. formSearch
  222. getList();
  223. };
  224. // 表单重置
  225. const handleFormReset = () => {
  226. formSearch.value = {
  227. channelId: null, // 渠道ID
  228. channelName: null, // 渠道名称
  229. channelAccount: "", // 渠道账号
  230. channelStatus: null, // 渠道状态
  231. loginType: null, // 登录类型
  232. limit: 20, // 当前页数量(查询量)
  233. page: 1, // 当前页码
  234. pageSizes: 20, // 总页数
  235. };
  236. getList();
  237. };
  238. // 选择监听器
  239. const handleSelectionChange = (val) => {
  240. context.emit("selection-change", val);
  241. };
  242. // 弹窗
  243. const layer = ref({
  244. show: false,
  245. title: "新增App",
  246. showButton: true,
  247. width: "50vw",
  248. edit: false,
  249. });
  250. const formEdit = ref({
  251. apiKey: "", //请求秘钥
  252. apiSecret: "", //请求密令
  253. channelAccount: "", //渠道账号
  254. channelId: "", //渠道ID
  255. channelName: "", //渠道名称
  256. channelPwd: "", //渠道密码
  257. channelStatus: 0, //渠道状态
  258. loginType: 0, //登录类型 1-账号密码 2-微信
  259. remark: "", //备注
  260. });
  261. const edit = (row) => {
  262. ruleForm.value?.resetFields();
  263. if (row) {
  264. layer.value.title = "编辑代理";
  265. layer.value.edit = true;
  266. formEdit.value = row;
  267. } else {
  268. layer.value.title = "新增代理";
  269. layer.value.edit = false;
  270. formEdit.value = {};
  271. }
  272. layer.value.show = true;
  273. };
  274. const ruleForm = ref(null);
  275. const rules = reactive({
  276. /* formEditbannedLimit: [
  277. { required: true, message: "请输入封禁期限", trigger: "blur" },
  278. ],
  279. bannedReason: [
  280. {
  281. required: true,
  282. message: "请输入封禁原因",
  283. trigger: "blur",
  284. },
  285. ], */
  286. });
  287. const submit = async (formEl) => {
  288. await formEl.validate(async (valid, fields) => {
  289. if (valid) {
  290. // 提交内容
  291. if (layer.value.edit) {
  292. await channelUpdateOne({ ...formEdit.value });
  293. } else {
  294. await channelAddOne({ ...formEdit.value });
  295. }
  296. ElMessage.success("新增成功");
  297. layer.value.show = false;
  298. } else {
  299. console.log("error submit!", fields);
  300. }
  301. });
  302. };
  303. // 删除
  304. const removeAgency = async (row) => {
  305. await channelDeleteOne({ channelId: row.channelId }).then((res) => {
  306. ElMessage.success("删除成功");
  307. });
  308. };
  309. </script>
  310. <style scoped lang="scss">
  311. .layout-container {
  312. .card {
  313. .title {
  314. margin-bottom: 10px;
  315. font-weight: 600;
  316. }
  317. display: flex;
  318. flex-direction: column;
  319. align-items: start;
  320. width: calc(100% - 60px);
  321. margin: 30px 30px 0;
  322. }
  323. .button {
  324. display: flex;
  325. flex-direction: column;
  326. .button-item {
  327. margin: 4px;
  328. }
  329. }
  330. }
  331. </style>