diff --git a/code/.gitignore b/code/.gitignore
index 07d8289e..70a3f6dd 100644
--- a/code/.gitignore
+++ b/code/.gitignore
@@ -26,8 +26,8 @@ dist/
#be
.vs/
-bin/
-obj/
+bin
+obj
*.suo
*.user
*.db
diff --git a/code/WebApp/vanilla/app.js b/code/WebApp/vanilla/app.js
index 9f35eb2c..34b69c72 100644
--- a/code/WebApp/vanilla/app.js
+++ b/code/WebApp/vanilla/app.js
@@ -6,12 +6,11 @@ import { Suspense, reactive, onMounted } from "vue";
export default {
components: { ElConfigProvider, Suspense },
- template: html`
+ template: html`
- Loading...
- `,
+ `,
setup() {
const localeMap = reactive(
new Map([
diff --git a/code/WebApp/vanilla/components/form/form-input.js b/code/WebApp/vanilla/components/form/form-input.js
index a99cc6c0..6d133fc6 100644
--- a/code/WebApp/vanilla/components/form/form-input.js
+++ b/code/WebApp/vanilla/components/form/form-input.js
@@ -1,7 +1,7 @@
import html from "html";
-import { ref, reactive, watch } from "vue";
+import { ref, reactive, watch, onMounted } from "vue";
import { dayjs } from "element-plus";
-import { post } from "../../request/index.js";
+import request, { post } from "../../request/index.js";
export default {
template: html`
@@ -55,28 +55,25 @@ export default {
v-model="model[prop]"
type="password"
show-password
- v-if="schema.format==='password'"
+ v-if="schema.input==='password'"
/>
`,
- props: ["modelValue", "schema", "prop", "isReadOnly"],
+ props: ["modelValue", "schema", "prop", "isReadOnly", "mode"],
emit: ["update:modelValue"],
- async setup(props, context) {
+ setup(props, context) {
const model = reactive(props.modelValue);
watch(model, (value) => {
context.emit("update:modelValue", value);
});
/*start*/
const getDisabled = () => {
- if (props.isReadOnly && props.isReadOnly === true) {
+ if (props.mode==='details') {
return true;
}
- if (props.schema.displayOnly) {
- return true;
- }
- if (props.mode === "update" && props.schema.addOnly) {
+ if (props.mode === "update" && props.schema.readOnly) {
return true;
}
return false;
@@ -89,20 +86,22 @@ export default {
const selectProps = ref({});
const selectValues = ref([]);
const options = ref([]);
- if (props.schema.options) {
- options.value = props.schema.options;
- } else if (props.schema.url) {
- try {
- const url = `${props.schema.url}`;
- const result = await post(url, { queryAll: true, query: { isReadonly: null, isDisabled: null, order: null } });
- options.value = result.data?.items.map((o) => ({
- value: o[props.schema.value],
- label: o[props.schema.label],
- }));
- } catch (error) {
- console.log(error);
+ onMounted(async () => {
+ if (props.schema.options) {
+ options.value = props.schema.options;
+ } else if (props.schema.url) {
+ try {
+ const url = `${props.schema.url}`;
+ const result = await request(url, null, { method: "get" });
+ options.value = result.data?.items.map((o) => ({
+ value: o[props.schema.value],
+ label: o[props.schema.label],
+ }));
+ } catch (error) {
+ console.log(error);
+ }
}
- }
+ });
return {
model,
getDisabled,
diff --git a/code/WebApp/vanilla/components/form/form-item.js b/code/WebApp/vanilla/components/form/form-item.js
index ae49e013..1616337b 100644
--- a/code/WebApp/vanilla/components/form/form-item.js
+++ b/code/WebApp/vanilla/components/form/form-item.js
@@ -1,11 +1,13 @@
import html from "html";
import { defineAsyncComponent, ref, reactive, watch } from "vue";
+import { format } from "../../utils/index.js";
+import { messages } from "../../utils/validation.js";
export default {
name: "formItem",
components: { AppFormInput: defineAsyncComponent(() => import("./form-input.js")) },
template: html`
-
+
-
+
`,
props: ["modelValue", "mode", "parentSchema", "schema", "prop", "errors"],
emit: ["update:modelValue"],
- async setup(props, context) {
+ setup(props, context) {
const model = reactive(props.modelValue);
watch(model, (value) => {
context.emit("update:modelValue", value);
@@ -63,18 +65,18 @@ export default {
}
if (!rule.message) {
if (rule.required) {
- rule.message = format(schema.messages.required, property.title);
+ rule.message = format(messages.required, property.title);
} else if (rule.pattern) {
- rule.message = format(schema.messages.pattern, property.title);
+ rule.message = format(messages.pattern, property.title);
} else if (property.type === "string" || property.type === "number" || property.type === "array") {
if (rule.len) {
- rule.message = format(schema.messages[property.type].len, property.title, rule.len);
+ rule.message = format(messages[property.type].len, property.title, rule.len);
} else if (rule.min) {
- rule.message = format(schema.messages[property.type].min, property.title, rule.min);
+ rule.message = format(messages[property.type].min, property.title, rule.min);
} else if (rule.max) {
- rule.message = format(schema.messages[property.type].max, property.title, rule.max);
+ rule.message = format(messages[property.type].max, property.title, rule.max);
} else if (rule.range) {
- rule.message = format(schema.messages[property.type].range, property.title, rule.range);
+ rule.message = format(messages[property.type].range, property.title, rule.range);
}
}
}
diff --git a/code/WebApp/vanilla/components/icon/index.js b/code/WebApp/vanilla/components/icon/index.js
index af87437d..df178a82 100644
--- a/code/WebApp/vanilla/components/icon/index.js
+++ b/code/WebApp/vanilla/components/icon/index.js
@@ -14,7 +14,7 @@ export default {
default: "file",
},
},
- async setup(props) {
+ setup(props) {
const svg = ref(null);
onMounted(async () => {
if (!props.name.startsWith("ep-")) {
diff --git a/code/WebApp/vanilla/components/list/index.js b/code/WebApp/vanilla/components/list/index.js
index 7b64f541..82a456cc 100644
--- a/code/WebApp/vanilla/components/list/index.js
+++ b/code/WebApp/vanilla/components/list/index.js
@@ -3,10 +3,11 @@ import request, { get, post } from "../../request/index.js";
import { defineAsyncComponent, ref, reactive, onMounted } from "vue";
import { useRoute, useRouter } from "vue-router";
import { useI18n } from "vue-i18n";
-import { listToTree, schemaToModel } from "../../utils/index.js";
+import { listToTree, schemaToModel, importFunction } from "../../utils/index.js";
import qs from "../../lib/qs/shim.js";
import VueOfficeExcel from "@vue-office/excel";
import { camelCase, capitalize } from "lodash";
+import { useAppStore } from "../../store/index.js";
export default {
name: "AppList",
@@ -40,6 +41,7 @@ export default {
:class="item.meta.htmlClass??'el-button--primary'"
v-if="item.meta.isTop"
@click="click(item,selectedRows)"
+ :disabled="item.meta.disabled && item.meta.disabled(selectedRows)"
>
{{item.meta.title}}
@@ -68,7 +70,7 @@ export default {
border
fit
>
-
+
{{ (pageModel.pageIndex - 1) * pageModel.pageSize + scope.$index + 1 }}
@@ -89,7 +91,7 @@ export default {
-
+
@@ -99,7 +101,7 @@ export default {
{{item.title}}
-
+
@@ -120,6 +122,7 @@ export default {
:class="item.meta.htmlClass??'el-button--primary'"
v-if="!item.meta.isTop"
@click="click(item,[scope.row])"
+ :disabled="item.meta.disabled && item.meta.disabled(scope.row)"
>
{{item.meta.title}}
@@ -136,7 +139,7 @@ export default {
@@ -321,13 +324,13 @@ export default {
`,
props: ["modelValue", "config", "querySchema", "controller", "query", "buttons"],
emits: ["command"],
- async setup(props, context) {
- // 变量定义
- //// 配置
- const config = ref(props.config);
- //// 分页
+ setup(props, context) {
+ /*变量定义*/
+ // 配置
+ const config = reactive(props.config);
+ // 分页
const pageModel = reactive({
- sizeList: [20, 50, 100],
+ sizeList: [1, 50, 100],
pageIndex: 1,
pageSize: 10,
total: 0,
@@ -348,7 +351,8 @@ export default {
const route = useRoute();
const router = useRouter();
const { t } = useI18n();
- const buttons = ref(props.buttons ?? route.meta.children);
+ const appStore = useAppStore();
+ const buttons = ref(props.buttons ?? route.meta.children.filter((o) => o.meta.hasPermission));
const baseUrl = props.controller ?? `${route.meta.path}`;
const indexUrl = props.indexUrl ?? `${baseUrl}/index`;
const queryModel = ref({});
@@ -405,7 +409,7 @@ export default {
queryModel.value.orderBy = Array.from(sortColumns.value)
.map((o) => capitalize(o[0]) + (o[1] === "ascending" ? "" : ` DESC`))
.join(",");
- await load(indexUrl);
+ await load();
};
const showColumn = (item, prop) => {
return (
@@ -417,10 +421,16 @@ export default {
};
const handleSelectionChange = (rows) => (selectedRows.value = rows);
- const load = async (url) => {
+ const load = async () => {
tableLoading.value = true;
try {
- const url = config.value.query.url;
+ const url = config.query.url;
+ const method = config.query.method;
+ //
+ queryModel.value = schemaToModel(config.query.schema);
+ queryModel.value.maxResultCount = pageModel.pageSize;
+ queryModel.value.skipCount = (pageModel.pageIndex - 1) * pageModel.pageSize;
+ //
const postData = JSON.parse(JSON.stringify(queryModel.value));
postData.filters = queryList.value.filter((o) => o.property && o.value);
if (postData.items) {
@@ -429,60 +439,61 @@ export default {
if (postData.query?.id) {
delete postData.query["id"];
}
- const listData = (await request(url, postData, { method: config.value.query.method.toUpperCase() })).data;
+ const listData = (await request(url, postData, { method })).data;
const items = listData.items;
if (tableSchema.value.isTree) {
items = listToTree(listData.items);
}
tableData.value = items;
+ pageModel.total = listData.totalCount;
//data.value = listData;
- queryModel.tableKey.value = !tableKey.value;
+ tableKey.value = !tableKey.value;
} catch (error) {
console.log(error);
} finally {
tableLoading.value = false;
}
};
- const onPageIndexChange = async () => {
- await load(indexUrl);
- };
- const onPageSizeChange = async () => await load(indexUrl);
+ const onPageIndexChange = async () => await load();
+ const onPageSizeChange = async () => await load();
const click = async (item, rows) => {
editFormloading.value = true;
editFormMode.value = item.path ?? item;
context.emit("command", item, rows);
if (item.path === "index") {
//list
- await load(indexUrl);
+ await load();
} else if (item.path === "details") {
//details
const url = `${baseUrl}/${item.path}?${qs.stringify({ id: rows[0].id })}`;
editFormSchema.value = (await get(url)).data;
editFormModel.value = (await post(url)).data;
- editFormTitle.value = `${querySchema.value?.title}${t("details")}`;
+ editFormTitle.value = `${config.edit.schema.title}${t("details")}`;
dialogVisible.value = true;
} else if (item.path === "create" || item.path === "update") {
//create
- let url = `${baseUrl}/${item.path}`;
- if (item.path === "update") {
- url = `${url}?${qs.stringify({ id: rows[0].id })}`;
+ if (item.path === "create") {
+ editFormModel.value = schemaToModel(config.edit.schema);
+ } else {
+ const url = `${config.edit.updateUrl ?? config.query.url}/${rows[0].id}`;
+ editFormModel.value = (await request(url, null, { method: "get" })).data;
}
- const vm = (await get(url)).data;
- editFormSchema.value = vm.schema;
- editFormModel.value = vm.model;
- editFormTitle.value = `${t(item.path)}${querySchema.value?.title}`;
+ editFormTitle.value = `${t(item.path)}${config.edit.schema.title}`;
dialogVisible.value = true;
} else if (item.path === "delete") {
//delete
- if (!rows.length) {
+ if (item.meta.isTop) {
+ // 批量删除
return;
+ } else {
+ // 单个删除
}
const url = `${baseUrl}/${item.path}`;
- await post(
- url,
- rows.map((o) => o.id)
- );
- await load(indexUrl);
+ // await post(
+ // url,
+ // rows.map((o) => o.id)
+ // );
+ await load();
} else if (item.path === "export") {
//export
editFormTitle.value = `${t(item.path)}${querySchema.value?.title}`;
@@ -505,12 +516,14 @@ export default {
const valid = await editFormRef.value.validate();
if (valid) {
editFormloading.value = true;
- const url = `${baseUrl}/${editFormMode.value}`;
- const result = await post(url, editFormModel.value);
+ const url =
+ (editFormMode.value === "create" ? config.edit.createUrl : config.edit.updateUrl) ?? config.query.url;
+ const method = editFormMode.value === "create" ? config.edit.createMethod : config.edit.updateMethod;
+ const result = await request(url, editFormModel.value, { method });
if (result.errors) {
model.errors = result.errors; //??
} else {
- await load(indexUrl);
+ await load();
editFormMode.value = null;
dialogVisible.value = false;
}
@@ -543,9 +556,9 @@ export default {
const response = await post(url, formData);
editFormloading.value = false;
dialogVisible.value = false;
- await load(indexUrl);
+ await load();
} else if (editFormMode.value === "filter") {
- await load(indexUrl);
+ await load();
dialogVisible.value = false;
}
};
@@ -596,7 +609,19 @@ export default {
const handleChange = (uploadFile, uploadFiles) => {
fileList.value = uploadFiles;
};
+ const getButtonDisabled = async (src, row) => {
+ if (src) {
+ const method = await importFunction(src);
+ return src.startsWith("async") ? await method(row) : method(row);
+ }
+ return false;
+ };
onMounted(async () => {
+ for (const item of route.meta.children) {
+ if (item.meta.disabled?.constructor === String) {
+ item.meta.disabled = await importFunction(item.meta.disabled);
+ }
+ }
pushQueryList();
// if (!querySchema.value) {
// const vm = (await get(indexUrl)).data;
@@ -609,17 +634,16 @@ export default {
// getSortModel(data.value);
// getColumns(vm.schema.properties.query);
// }
- if (!config.value) {
+ if (!config) {
//
}
- getColumns(config.value.table.schema);
- queryModel.value = schemaToModel(config.value.query.schema);
+ getColumns(config.table.schema);
if (props.query) {
Object.assign(queryModel.value.query, props.query);
}
// getSortModel(data.value);
// getColumns(vm.schema.properties.query);
- await load(indexUrl);
+ await load();
});
return {
config,
@@ -664,6 +688,7 @@ export default {
pushQueryList,
fileList,
handleChange,
+ getButtonDisabled,
};
},
};
diff --git a/code/WebApp/vanilla/config/settings.js b/code/WebApp/vanilla/config/settings.js
index c913e2a8..b1ced859 100644
--- a/code/WebApp/vanilla/config/settings.js
+++ b/code/WebApp/vanilla/config/settings.js
@@ -1,4 +1,5 @@
export default {
enableLocale: false,
baseURL: "http://dev.ccwin-in.com:10582/api",
+ //baseURL: "http://localhost:10130/api",
};
diff --git a/code/WebApp/vanilla/models/login.js b/code/WebApp/vanilla/models/login.js
index f4cf7243..928f1309 100644
--- a/code/WebApp/vanilla/models/login.js
+++ b/code/WebApp/vanilla/models/login.js
@@ -20,7 +20,7 @@ export default function () {
password: {
title: "密码",
type: "string",
- format: "password",
+ input: "password",
rules: [
{
required: true,
diff --git a/code/WebApp/vanilla/models/user.js b/code/WebApp/vanilla/models/user.js
index 6eee1306..08960eba 100644
--- a/code/WebApp/vanilla/models/user.js
+++ b/code/WebApp/vanilla/models/user.js
@@ -5,6 +5,7 @@ const schema = {
userName: {
title: "用户名",
type: "string",
+ readOnly: true, //
showForList: true,
rules: [
{
@@ -16,10 +17,14 @@ const schema = {
},
],
},
- phoneNumber: {
- title: "电话",
+ password: {
+ title: "密码",
type: "string",
input: "password",
+ },
+ name: {
+ title: "姓名",
+ type: "string",
showForList: true,
rules: [
{
@@ -27,8 +32,8 @@ const schema = {
},
],
},
- name: {
- title: "姓名",
+ phoneNumber: {
+ title: "电话",
type: "string",
showForList: true,
rules: [
@@ -52,26 +57,30 @@ const schema = {
type: "array",
input: "select",
multiple: true,
- },
- password: {
- title: "密码",
- type: "string",
- input: "password",
- rules: [
- {
- required: true,
- message: "密码不能为空",
- },
- ],
+ url: "identity/roles/all",
+ value: "name",
+ label: "name",
+ items: {
+ type: "string",
+ },
},
},
};
+const url = "base/user";
+const createUrl = url;
+const updateUrl = url;
+const deleteUrl = "api/identity/users";
+const method = "get";
+const createMethod = "post";
+const updateMethod = "put";
+const deleteMethod = "delete";
+
export default function () {
return {
query: {
- url: "base/user",
- method: "get",
+ url,
+ method,
schema: {
title: "用户",
type: "object",
@@ -93,6 +102,16 @@ export default function () {
},
table: {
schema: schema,
+ selectable: (o) => o.name !== "admin",
+ },
+ edit: {
+ createUrl,
+ updateUrl,
+ deleteUrl,
+ createMethod,
+ updateMethod,
+ deleteMethod,
+ schema: schema,
},
};
}
diff --git a/code/WebApp/vanilla/request/index.js b/code/WebApp/vanilla/request/index.js
index 9f22fc74..4c9a8ab7 100644
--- a/code/WebApp/vanilla/request/index.js
+++ b/code/WebApp/vanilla/request/index.js
@@ -17,7 +17,7 @@ const addToken = async (options) => {
};
const getUrl = (url) => {
- if (url.indexOf("/") === 0) {
+ if (url.startsWith("http")) {
return url;
}
let result = settings.baseURL;
@@ -111,13 +111,28 @@ async function request(url, data, options, withoutToken = false) {
url = getUrl(url);
let defaultOptions = {
method: "POST",
- headers: { "Accept-Language": "zh-Hans" },
+ headers: {
+ "Accept-Language": "zh-Hans",
+ "Content-Type": "application/json",
+ },
};
if (options) {
Object.assign(defaultOptions, options);
}
- if (defaultOptions.method !== "GET" && !(data instanceof FormData)) {
- defaultOptions.headers["Content-Type"] = "application/json";
+ if (defaultOptions.method === "GET" && data) {
+ url = `${url}?${qs.stringify(data)}`;
+ }
+ if (defaultOptions.method === "POST") {
+ if (data instanceof FormData) {
+ delete defaultOptions.headers["Content-Type"];
+ }
+ if (defaultOptions.headers["Content-Type"]?.startsWith("application/x-www-form-urlencoded")) {
+ defaultOptions.body = qs.stringify(data);
+ } else if (defaultOptions.headers["Content-Type"]?.startsWith("application/json")) {
+ defaultOptions.body = JSON.stringify(data);
+ } else {
+ defaultOptions.body = data;
+ }
}
if (!withoutToken) {
await addToken(defaultOptions);
diff --git a/code/WebApp/vanilla/router/routes.js b/code/WebApp/vanilla/router/routes.js
index 040b068e..ed43f2aa 100644
--- a/code/WebApp/vanilla/router/routes.js
+++ b/code/WebApp/vanilla/router/routes.js
@@ -52,6 +52,7 @@ export default [
title: "删除",
icon: "file",
permission: "AbpIdentity.Users.Delete",
+ isTop: true,
},
},
],
@@ -83,6 +84,7 @@ export default [
icon: "file",
htmlClass: "el-button--primary",
permission: "AbpIdentity.Users.Update",
+ disabled: `(o) => o.isStatic`,
},
},
{
@@ -92,6 +94,7 @@ export default [
title: "删除",
icon: "file",
permission: "AbpIdentity.Users.Delete",
+ disabled: `(o) => o.isStatic`,
},
},
],
diff --git a/code/WebApp/vanilla/utils/index.js b/code/WebApp/vanilla/utils/index.js
index 17c53dba..2c8dcb77 100644
--- a/code/WebApp/vanilla/utils/index.js
+++ b/code/WebApp/vanilla/utils/index.js
@@ -120,5 +120,28 @@ function getFileName(contentDisposition) {
return decodeURIComponent(/filename\*=UTF-8''([\w%\-\.]+)(?:; ?|$)/i.exec(contentDisposition)[1]);
}
+async function importModule(input) {
+ const dataUri = `data:text/javascript;charset=utf-8,${encodeURIComponent(input)}`;
+ const result = await import(dataUri /* @vite-ignore */);
+ return result.default;
+}
+
+// await importFunction('()=>console.log(123)');
+async function importFunction(input) {
+ const src = input ?? `()=>{}`;
+ const result = await importModule(`export default ${src}`);
+ return result;
+}
+
export default html;
-export { persentFormat, bytesFormat, format, schemaToModel, listToTree, treeToList, getProp, getFileName };
+export {
+ persentFormat,
+ bytesFormat,
+ format,
+ schemaToModel,
+ listToTree,
+ treeToList,
+ getProp,
+ getFileName,
+ importFunction,
+};
diff --git a/code/WebApp/vanilla/utils/validation.js b/code/WebApp/vanilla/utils/validation.js
new file mode 100644
index 00000000..29bd903a
--- /dev/null
+++ b/code/WebApp/vanilla/utils/validation.js
@@ -0,0 +1,113 @@
+const messages = {
+ default: "%s验证失败",
+ required: "%s是必填项",
+ enum: "%s必须是%s之一",
+ whitespace: "%s不能为空",
+ // date: {
+ // format: '%s date %s is invalid for format %s',
+ // parse: '%s date could not be parsed, %s is invalid ',
+ // invalid: '%s date %s is invalid',
+ // },
+ types: {
+ string: "%s不是有效的字符串",
+ method: "%s不是有效的函数",
+ array: "%s不是有效的数组",
+ object: "%s不是有效的对象",
+ number: "%s不是有效的数字",
+ date: "%s不是有效的日期",
+ boolean: "%s不是有效的布尔值",
+ integer: "%s不是有效的整数",
+ float: "%s不是有效的浮点数",
+ regexp: "%s不是有效的正则表达式",
+ email: "%s不是有效的邮箱",
+ url: "%s不是有效的 url",
+ hex: "%s不是有效的十六进制",
+ },
+ string: {
+ len: "%s长度必须是%s",
+ min: "%s最小长度为%s",
+ max: "%s最大长度为%s",
+ range: "%s长度必须在%s和%s之间",
+ },
+ number: {
+ len: "%s必须等于%s",
+ min: "%s不小于%s",
+ max: "%s不大于%s",
+ range: "%s必须在%s和%s之间",
+ },
+ array: {
+ len: "%s的数量必须是%s",
+ min: "%s的数量不小于%s",
+ max: "%s的数量不大于%s",
+ range: "%s的数量必须在%s和%s之间",
+ },
+ pattern: {
+ mismatch: "%s的值 %s 不匹配模式 %s",
+ },
+ clone: function clone() {
+ const cloned = JSON.parse(JSON.stringify(this));
+ cloned.clone = this.clone;
+ return cloned;
+ },
+ //
+ compare: "%s 和 %s 输入必须一致",
+ true: "%s必须选中",
+ remote: "%s远程验证失败",
+};
+
+const validators = {
+ compare(rule, value, callback, source, options) {
+ const errors = [];
+ if (value && value !== rule.data[rule.compare]) {
+ const message = format(options.messages.compare, rule.title, rule.schema.properties[rule.compare].title);
+ errors.push(new Error(message));
+ }
+ callback(errors);
+ },
+ true(rule, value, callback, source, options) {
+ const errors = [];
+ if (!value) {
+ const message = format(options.messages.true, rule.title);
+ errors.push(new Error(message));
+ }
+ callback(errors);
+ },
+ remote(rule, value, callback, source, options) {
+ const errors = [];
+ const message = format(options.messages.remote, rule.title);
+ if (!value) {
+ callback(errors);
+ } else {
+ const config = {
+ url: rule.url,
+ method: rule.method ?? "get",
+ };
+ const data = { [rule.field]: value };
+ if (config.method === "get") {
+ config.params = data;
+ } else {
+ config.data = data;
+ }
+ request
+ .request(config)
+ .then((response) => {
+ if (response.status === 200) {
+ if (response.data.code) {
+ if (response.data.code !== 200) {
+ errors.push(new Error(1 + response.data.message));
+ }
+ }
+ } else {
+ errors.push(new Error(2 + response.data));
+ }
+ callback(errors);
+ })
+ .catch((o) => {
+ errors.push(o.response?.data?.message ?? message ?? o.message);
+ callback(errors);
+ });
+ }
+ },
+};
+
+export { messages };
diff --git a/code/WebApp/vanilla/views/login.js b/code/WebApp/vanilla/views/login.js
index fbd59cd1..832c0adb 100644
--- a/code/WebApp/vanilla/views/login.js
+++ b/code/WebApp/vanilla/views/login.js
@@ -3,7 +3,7 @@ import { ref, reactive } from "vue";
import AppForm from "../components/form/index.js";
import { login, setRefreshToken, getUser, setAccessToken } from "../api/user.js";
import router, { refreshRouter } from "../router/index.js";
-import { post } from "../request/index.js";
+import request, { post } from "../request/index.js";
import LayoutLogo from "../layouts/logo.js";
import LayoutLocale from "../layouts/locale.js";
import LayoutFooter from "../layouts/footer.js";
@@ -26,21 +26,16 @@ export default {
`,
- async setup() {
+ setup() {
const schema = reactive(useLoginModel());
const model = reactive(schemaToModel(schema));
const submit = async (callback, loading) => {
try {
- const url = "connect-token";
+ const url = "base/token";
const appStore = useAppStore();
- const result = await post(
- url,
- model,
- { headers: { "Content-Type": "application/x-www-form-urlencoded" } },
- true
- );
+ const result = await request(url, model, { method: "POST" }, true);
if (!result.errors) {
- appStore.token = result.data.access_token;
+ appStore.token = result.data.accessToken;
setAccessToken(appStore.token);
//setRefreshToken(result.data.refresh_token);
appStore.user = await getUser();
diff --git a/code/src/Modules/BaseService/BaseService.Application.Contracts/Systems/UserManagement/IUserAppService.cs b/code/src/Modules/BaseService/BaseService.Application.Contracts/Systems/UserManagement/IUserAppService.cs
index d1efe788..83a58daa 100644
--- a/code/src/Modules/BaseService/BaseService.Application.Contracts/Systems/UserManagement/IUserAppService.cs
+++ b/code/src/Modules/BaseService/BaseService.Application.Contracts/Systems/UserManagement/IUserAppService.cs
@@ -1,9 +1,7 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Threading.Tasks;
-using BaseService.BaseData.Permissions.Dto;
+using BaseService.BaseData.Permissions.Dto;
using BaseService.RelationData.Dto;
+using System;
+using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Identity;
@@ -17,7 +15,7 @@ namespace BaseService.Systems.UserManagement
///
///
///
- Task GetAsync(Guid id);
+ Task GetAsync(Guid id);
///
/// 获取当前登录用户信息
@@ -61,7 +59,6 @@ namespace BaseService.Systems.UserManagement
///
Task GetAuthConfigAsync(Guid branchId);
-
///
/// 重置当前登录用户的密码
///
@@ -70,6 +67,5 @@ namespace BaseService.Systems.UserManagement
///
//Task ResetPasswordCurrentUser(Guid id, IdentityUserCreateDto input);
Task ResetPasswordAsync(Guid id);
-
}
-}
+}
\ No newline at end of file
diff --git a/code/src/Modules/BaseService/BaseService.Application/BaseService.Application.csproj b/code/src/Modules/BaseService/BaseService.Application/BaseService.Application.csproj
index 7bf3e650..081c9073 100644
--- a/code/src/Modules/BaseService/BaseService.Application/BaseService.Application.csproj
+++ b/code/src/Modules/BaseService/BaseService.Application/BaseService.Application.csproj
@@ -7,7 +7,9 @@
+
+
diff --git a/code/src/Modules/BaseService/BaseService.Application/UserManagement/TokenAppService.cs b/code/src/Modules/BaseService/BaseService.Application/UserManagement/TokenAppService.cs
new file mode 100644
index 00000000..18a3c671
--- /dev/null
+++ b/code/src/Modules/BaseService/BaseService.Application/UserManagement/TokenAppService.cs
@@ -0,0 +1,55 @@
+using IdentityModel.Client;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Configuration;
+using System.ComponentModel.DataAnnotations;
+using System.Net.Http;
+using System.Threading.Tasks;
+using Volo.Abp.Application.Services;
+
+namespace BaseService.UserManagement
+{
+ [Route("api/base/token")]
+ public class UserAppService : ApplicationService
+ {
+ private readonly IHttpClientFactory _httpClientFactory;
+ private readonly IConfiguration _configuration;
+
+ public UserAppService(IHttpClientFactory httpClientFactory, IConfiguration configuration)
+ {
+ this._httpClientFactory = httpClientFactory;
+ this._configuration = configuration;
+ }
+
+ [HttpPost, AllowAnonymous, IgnoreAntiforgeryToken]
+ public async Task CreateAsync(LoginModel model)
+ {
+ var address = _configuration["AuthServer:Authority"];
+ var clientId = _configuration["AuthServer:ClientId"];
+ var clientSecret = _configuration["AuthServer:ClientSecret"];
+
+ var result = await _httpClientFactory.CreateClient().RequestPasswordTokenAsync(new PasswordTokenRequest
+ {
+ Address = $"{address.TrimEnd('/')}/connect/token",
+ GrantType = "password",
+ ClientId = clientId,
+ ClientSecret = clientSecret,
+ UserName = model.UserName,
+ Password = model.Password
+ }).ConfigureAwait(false);
+
+ return result;
+ }
+
+ public class LoginModel
+ {
+ [Display]
+ [Required]
+ public string UserName { get; set; }
+
+ [Display]
+ [Required]
+ public string Password { get; set; }
+ }
+ }
+}
\ No newline at end of file
diff --git a/code/src/Modules/BaseService/BaseService.Application/UserManagement/UserAppService.cs b/code/src/Modules/BaseService/BaseService.Application/UserManagement/UserAppService.cs
index b70e6b1c..609fc6ad 100644
--- a/code/src/Modules/BaseService/BaseService.Application/UserManagement/UserAppService.cs
+++ b/code/src/Modules/BaseService/BaseService.Application/UserManagement/UserAppService.cs
@@ -1,16 +1,15 @@
using BaseService.BaseData;
-using BaseService.Permissions;
+using BaseService.BaseData.Permissions.Dto;
using BaseService.RelationBaseData;
+using BaseService.RelationData.Dto;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
-using Microsoft.EntityFrameworkCore;
+using Omu.ValueInjecter;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
-using BaseService.BaseData.Permissions.Dto;
-using BaseService.RelationData.Dto;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
@@ -38,6 +37,7 @@ namespace BaseService.Systems.UserManagement
//权限提供者类
private readonly IAbpAuthorizationPolicyProvider _abpAuthorizationPolicyProvider;
+
private readonly IAuthorizationService _authorizationService;
protected ICurrentUser CurrentUsers { get; }
@@ -71,9 +71,11 @@ namespace BaseService.Systems.UserManagement
[HttpGet]
[Route("{id}")]
- public async Task GetAsync(Guid id)
+ public async Task GetAsync(Guid id)
{
- var dto = ObjectMapper.Map(await UserManager.GetByIdAsync(id));
+ var user = await UserManager.GetByIdAsync(id);
+ var dto = Mapper.Map(user);
+ dto.RoleNames = (await UserRepository.GetRoleNamesAsync(id)).ToArray();
return dto;
}
@@ -196,7 +198,7 @@ namespace BaseService.Systems.UserManagement
//获取用户的所有分支
var branchRoles = await GetUserBranchRolesAsync(CurrentUsers.GetId());
var groupBranchRoles = branchRoles.GroupBy(x => x.BranchId)
- .Select(y => new {xx = new {BranchId = y.Key}, items = y});
+ .Select(y => new { xx = new { BranchId = y.Key }, items = y });
foreach (var group in groupBranchRoles
)
{
@@ -225,7 +227,7 @@ namespace BaseService.Systems.UserManagement
//获取用户的所有分支
var branchRoles = await GetUserBranchRolesAsync(userId);
var groupBranchRoles = branchRoles.GroupBy(x => x.BranchId)
- .Select(y => new {xx = new {BranchId = y.Key}, items = y});
+ .Select(y => new { xx = new { BranchId = y.Key }, items = y });
foreach (var group in groupBranchRoles)
{
var mybranchrole = new BranchRoleDto
@@ -241,8 +243,6 @@ namespace BaseService.Systems.UserManagement
return new ListResultDto(branchList);
}
-
-
///
/// 根据用户ID,获取当前登录用户的所有权限信息,带角色名称
///
@@ -373,7 +373,6 @@ namespace BaseService.Systems.UserManagement
return authConfig;
}
-
///
/// 重置密码功能
///
diff --git a/code/src/Modules/BaseService/BaseService.Host/.config/dotnet-tools.json b/code/src/Modules/BaseService/BaseService.Host/.config/dotnet-tools.json
new file mode 100644
index 00000000..812c6cdb
--- /dev/null
+++ b/code/src/Modules/BaseService/BaseService.Host/.config/dotnet-tools.json
@@ -0,0 +1,12 @@
+{
+ "version": 1,
+ "isRoot": true,
+ "tools": {
+ "dotnet-ef": {
+ "version": "7.0.8",
+ "commands": [
+ "dotnet-ef"
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/code/src/Modules/BaseService/BaseService.Host/BaseServiceHostModule.cs b/code/src/Modules/BaseService/BaseService.Host/BaseServiceHostModule.cs
index a35e0903..40e83e97 100644
--- a/code/src/Modules/BaseService/BaseService.Host/BaseServiceHostModule.cs
+++ b/code/src/Modules/BaseService/BaseService.Host/BaseServiceHostModule.cs
@@ -1,39 +1,40 @@
-using System.Linq;
+using BaseService.EntityFrameworkCore;
+using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.DataProtection;
+using Microsoft.AspNetCore.Identity;
+using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
-using StackExchange.Redis;
using Microsoft.OpenApi.Models;
+using StackExchange.Redis;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Security.Claims;
using Volo.Abp;
+using Volo.Abp.AspNetCore.MultiTenancy;
+using Volo.Abp.AspNetCore.Mvc;
+using Volo.Abp.AspNetCore.Mvc.AntiForgery;
+using Volo.Abp.AspNetCore.Serilog;
using Volo.Abp.Auditing;
using Volo.Abp.Autofac;
+using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.Identity;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
-using Volo.Abp.AspNetCore.MultiTenancy;
-using System;
-using Volo.Abp.TenantManagement;
-using Volo.Abp.Threading;
-using Volo.Abp.Data;
-using Volo.Abp.AspNetCore.Serilog;
-using Volo.Abp.PermissionManagement.HttpApi;
-using Microsoft.AspNetCore.Cors;
using Volo.Abp.MultiTenancy;
-using BaseService.EntityFrameworkCore;
-using System.Collections.Generic;
-using Microsoft.AspNetCore.Authentication.JwtBearer;
+using Volo.Abp.PermissionManagement.HttpApi;
using Volo.Abp.Security.Claims;
-using System.Security.Claims;
-using Volo.Abp.AspNetCore.Mvc;
-using Microsoft.Extensions.Configuration;
-using Microsoft.AspNetCore.Identity;
+using Volo.Abp.TenantManagement;
+using Volo.Abp.Threading;
+
//using Win.Sfs.SettleAccount;
//using Win.Sfs.BaseData;
//using BaseData;
-
namespace BaseService
{
[DependsOn(
@@ -45,8 +46,8 @@ namespace BaseService
typeof(AbpPermissionManagementHttpApiModule),
typeof(AbpTenantManagementHttpApiModule),
typeof(AbpIdentityHttpApiModule),
- // typeof(BaseDataHttpApiModule),
- //typeof(BaseDataApplicationContractsModule),
+ // typeof(BaseDataHttpApiModule),
+ //typeof(BaseDataApplicationContractsModule),
//typeof(SettleAccountHttpApiModule),
typeof(AbpAspNetCoreSerilogModule)
)]
@@ -56,12 +57,15 @@ namespace BaseService
public override void ConfigureServices(ServiceConfigurationContext context)
{
+ context.Services.AddHttpClient();
+ Configure(O => O.AutoValidate = false);
+
var configuration = context.Services.GetConfiguration();
ConfigureConventionalControllers();
-
+
ConfigureMultiTenancy();
-
+
ConfigureJwt(context, configuration);
ConfigureSwagger(context);
@@ -73,7 +77,7 @@ namespace BaseService
ConfigureAuditing();
ConfigureCros(context, configuration);
-
+
ConfigureLocalization();
ConfigurePasswordSet(context);
@@ -87,6 +91,7 @@ namespace BaseService
options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文"));
});
}
+
///
/// 设置密码强度
///
@@ -148,7 +153,6 @@ namespace BaseService
var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]);
context.Services.AddDataProtection()
.PersistKeysToStackExchangeRedis(redis, "DataProtection-Keys");
-
}
private void ConfigureDbContext()
@@ -160,15 +164,15 @@ namespace BaseService
{
context.Services.AddSwaggerGen(options =>
{
- options.SwaggerDoc("v1", new OpenApiInfo {Title = "BaseService Service API", Version = "v1"});
+ options.SwaggerDoc("v1", new OpenApiInfo { Title = "BaseService Service API", Version = "v1" });
options.DocInclusionPredicate((docName, description) => true);
options.CustomSchemaIds(type => type.FullName);
options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
- Description = "请输入JWT令牌,例如:Bearer 12345abcdef",
+ Description = "请输入 JWT Token",
Name = "Authorization",
In = ParameterLocation.Header,
- Type = SecuritySchemeType.ApiKey,
+ Type = SecuritySchemeType.Http,
Scheme = "Bearer"
});
@@ -177,16 +181,9 @@ namespace BaseService
{
new OpenApiSecurityScheme
{
- Reference = new OpenApiReference
- {
- Type = ReferenceType.SecurityScheme,
- Id = "Bearer"
- },
- Scheme = "oauth2",
- Name = "Bearer",
- In = ParameterLocation.Header,
+ Reference = new OpenApiReference {Type = ReferenceType.SecurityScheme, Id = "Bearer"}
},
- new List()
+ new string[] { }
}
});
});
@@ -224,6 +221,7 @@ namespace BaseService
;
});
}
+
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
var app = context.GetApplicationBuilder();
@@ -273,4 +271,4 @@ namespace BaseService
});
}
}
-}
+}
\ No newline at end of file
diff --git a/code/src/Modules/BaseService/BaseService.Host/appsettings.json b/code/src/Modules/BaseService/BaseService.Host/appsettings.json
index 8050d6cc..73b75822 100644
--- a/code/src/Modules/BaseService/BaseService.Host/appsettings.json
+++ b/code/src/Modules/BaseService/BaseService.Host/appsettings.json
@@ -1,11 +1,14 @@
{
"AuthServer": {
- "Authority": "http://dev.ccwin-in.com:10580"
+ "Authority": "http://dev.ccwin-in.com:10580",
+ "ClientId": "basic-web",
+ "ClientSecret": ""
},
"App": {
"CorsOrigins": "http://localhost:9527,http://dev.ccwin-in.com:10588,http://localhost:44307"
},
"ConnectionStrings": {
+ //"Default": "Server=localhost;Database=BJABP;User ID=sa;Password=aA123456!;Trusted_Connection=False;TrustServerCertificate=True",
"Default": "Server=dev.ccwin-in.com,13319;Database=BJABP;User ID=ccwin-in;Password=Microsoft@2022;Trusted_Connection=False;TrustServerCertificate=True"
},
"ElasticSearch": {
@@ -19,22 +22,7 @@
"Default": "Warning"
}
},
-<<<<<<< HEAD
- //"Settings": {
- // "Abp.Localization.DefaultLanguage": "zh-Hans",
- // "Abp.Identity.Password.RequireNonAlphanumeric": "false", //ȥ�����ĸ����
- // "Abp.Identity.Password.RequireUppercase": "false", //ȥ���д����
- // "Abp.Identity.Password.RequireLowercase": "false", //ȥ��Сд
- // "Abp.Identity.Password.RequiredLength": "1",
- // "Abp.Identity.SignIn.RequireConfirmedEmail": "true",
- // //�����û�����
- // "Abp.Identity.Lockout.AllowedForNewUsers": "true",
- // "Abp.Identity.Lockout.MaxFailedAccessAttempts": "3"
- //},
- "AllowedHosts": "*"
-=======
"AllowedHosts": "*",
"RePassword": "111111"
->>>>>>> 1c2946500765850db29fa7d216f5e55e2e4de888
}
diff --git a/docs/20230711-151906.jpg b/docs/20230711-151906.jpg
new file mode 100644
index 00000000..9428c337
Binary files /dev/null and b/docs/20230711-151906.jpg differ
diff --git a/docs/SqlSchemaCompare2.scmp b/docs/SqlSchemaCompare2.scmp
new file mode 100644
index 00000000..4c5931b6
--- /dev/null
+++ b/docs/SqlSchemaCompare2.scmp
@@ -0,0 +1,1021 @@
+
+
+ 10
+
+
+ Data Source=localhost;Initial Catalog=BJABP;Persist Security Info=False;User ID=sa;Pooling=False;Multiple Active Result Sets=False;Connect Timeout=60;Encrypt=False;Trust Server Certificate=False;Command Timeout=0
+
+
+
+
+ Data Source=dev.ccwin-in.com,13319;Initial Catalog=BJABP;Persist Security Info=True;User ID=ccwin-in;Pooling=False;Multiple Active Result Sets=False;Connect Timeout=60;Encrypt=False;Trust Server Certificate=False;Command Timeout=0
+
+
+
+
+
+ Version
+ 1
+
+
+
+
+ PlanGenerationType
+ SqlDeploymentOptions
+
+
+ AllowExistingModelErrors
+ False
+
+
+ AllowIncompatiblePlatform
+ False
+
+
+ BackupDatabaseBeforeChanges
+ False
+
+
+ IgnoreIndexesStatisticsOnEnclaveEnabledColumns
+ False
+
+
+ BlockOnPossibleDataLoss
+ True
+
+
+ BlockWhenDriftDetected
+ False
+
+
+ CompareUsingTargetCollation
+ False
+
+
+ CommentOutSetVarDeclarations
+ False
+
+
+ CreateNewDatabase
+ False
+
+
+ DeployDatabaseInSingleUserMode
+ False
+
+
+ DisableAndReenableDdlTriggers
+ True
+
+
+ DisableIndexesForDataPhase
+ True
+
+
+ DisableParallelismForEnablingIndexes
+ False
+
+
+ DoNotAlterChangeDataCaptureObjects
+ True
+
+
+ DoNotAlterReplicatedObjects
+ True
+
+
+ DropConstraintsNotInSource
+ True
+
+
+ DropDmlTriggersNotInSource
+ True
+
+
+ DropExtendedPropertiesNotInSource
+ True
+
+
+ DropIndexesNotInSource
+ True
+
+
+ DropPermissionsNotInSource
+ False
+
+
+ DropObjectsNotInSource
+ True
+
+
+ DropRoleMembersNotInSource
+ False
+
+
+ DropStatisticsNotInSource
+ True
+
+
+ GenerateSmartDefaults
+ False
+
+
+ HashObjectNamesInLogs
+ False
+
+
+ IgnoreDdlTriggerOrder
+ False
+
+
+ IgnoreDdlTriggerState
+ False
+
+
+ IgnoreObjectPlacementOnPartitionScheme
+ True
+
+
+ IgnoreAuthorizer
+ False
+
+
+ IgnoreDefaultSchema
+ False
+
+
+ IgnoreRouteLifetime
+ True
+
+
+ IgnoreCryptographicProviderFilePath
+ True
+
+
+ IgnoreComments
+ False
+
+
+ IgnoreWhitespace
+ True
+
+
+ IgnoreKeywordCasing
+ True
+
+
+ IgnoreSemicolonBetweenStatements
+ True
+
+
+ IgnorePartitionSchemes
+ False
+
+
+ IgnoreTablePartitionOptions
+ False
+
+
+ IgnoreWithNocheckOnCheckConstraints
+ False
+
+
+ IgnoreWithNocheckOnForeignKeys
+ False
+
+
+ IgnoreIdentitySeed
+ False
+
+
+ IgnoreIncrement
+ False
+
+
+ IgnoreFillFactor
+ True
+
+
+ IgnoreIndexPadding
+ True
+
+
+ IgnoreColumnCollation
+ False
+
+
+ IgnoreColumnOrder
+ False
+
+
+ IgnoreLockHintsOnIndexes
+ False
+
+
+ IgnoreTableOptions
+ False
+
+
+ IgnoreIndexOptions
+ False
+
+
+ IgnoreDmlTriggerOrder
+ False
+
+
+ IgnoreDmlTriggerState
+ False
+
+
+ IgnoreAnsiNulls
+ True
+
+
+ IgnoreQuotedIdentifiers
+ True
+
+
+ IgnoreUserSettingsObjects
+ False
+
+
+ IgnoreFilegroupPlacement
+ True
+
+
+ IgnoreFullTextCatalogFilePath
+ True
+
+
+ IgnoreFileAndLogFilePath
+ True
+
+
+ IgnoreLoginSids
+ True
+
+
+ IgnoreNotForReplication
+ False
+
+
+ IgnoreFileSize
+ True
+
+
+ IgnoreSensitivityClassifications
+ False
+
+
+ AllowUnsafeRowLevelSecurityDataMovement
+ False
+
+
+ IncludeCompositeObjects
+ False
+
+
+ IncludeTransactionalScripts
+ False
+
+
+ IsAlwaysEncryptedParameterizationEnabled
+ False
+
+
+ NoAlterStatementsToChangeCLRTypes
+ False
+
+
+ PopulateFilesOnFileGroups
+ True
+
+
+ PreserveIdentityLastValues
+ False
+
+
+ RegisterDataTierApplication
+ False
+
+
+ RebuildIndexesOfflineForDataPhase
+ False
+
+
+ RestoreSequenceCurrentValue
+ True
+
+
+ ScriptDatabaseCollation
+ False
+
+
+ ScriptDatabaseCompatibility
+ False
+
+
+ ScriptDatabaseOptions
+ False
+
+
+ ScriptDeployStateChecks
+ False
+
+
+ ScriptFileSize
+ False
+
+
+ ScriptNewConstraintValidation
+ True
+
+
+ ScriptRefreshModule
+ True
+
+
+ TargetDatabaseName
+ BJABP
+
+
+ TargetConnectionString
+ Data Source=dev.ccwin-in.com,13319;Initial Catalog=BJABP;Persist Security Info=True;User ID=ccwin-in;Pooling=False;Multiple Active Result Sets=False;Connect Timeout=60;Encrypt=False;Trust Server Certificate=False;Application Name="Microsoft SQL Server Data Tools, Schema Compare";Command Timeout=0
+
+
+ TreatVerificationErrorsAsWarnings
+ False
+
+
+ UnmodifiableObjectWarnings
+ True
+
+
+ VerifyCollationCompatibility
+ True
+
+
+ VerifyDeployment
+ True
+
+
+ RunDeploymentPlanExecutors
+ False
+
+
+ AllowDropBlockingAssemblies
+ False
+
+
+ DoNotEvaluateSqlCmdVariables
+ True
+
+
+ DoNotDropAggregates
+ False
+
+
+ DoNotDropApplicationRoles
+ False
+
+
+ DoNotDropAssemblies
+ False
+
+
+ DoNotDropAsymmetricKeys
+ False
+
+
+ DoNotDropAudits
+ False
+
+
+ DoNotDropBrokerPriorities
+ False
+
+
+ DoNotDropCertificates
+ False
+
+
+ DoNotDropClrUserDefinedTypes
+ False
+
+
+ DoNotDropColumnEncryptionKeys
+ False
+
+
+ DoNotDropColumnMasterKeys
+ False
+
+
+ DoNotDropContracts
+ False
+
+
+ DoNotDropCredentials
+ False
+
+
+ DoNotDropDatabaseScopedCredentials
+ False
+
+
+ DoNotDropCryptographicProviders
+ False
+
+
+ DoNotDropDatabaseAuditSpecifications
+ False
+
+
+ DoNotDropDatabaseRoles
+ False
+
+
+ DoNotDropDatabaseTriggers
+ False
+
+
+ IgnoreDatabaseWorkloadGroups
+ False
+
+
+ DoNotDropDatabaseWorkloadGroups
+ False
+
+
+ IgnoreWorkloadClassifiers
+ False
+
+
+ DoNotDropWorkloadClassifiers
+ False
+
+
+ DoNotDropDefaults
+ False
+
+
+ DoNotDropEndpoints
+ False
+
+
+ DoNotDropErrorMessages
+ False
+
+
+ DoNotDropEventNotifications
+ False
+
+
+ DoNotDropEventSessions
+ False
+
+
+ DoNotDropExtendedProperties
+ False
+
+
+ DoNotDropExternalDataSources
+ False
+
+
+ DoNotDropExternalFileFormats
+ False
+
+
+ DoNotDropExternalLanguages
+ False
+
+
+ DoNotDropExternalLibraries
+ False
+
+
+ DoNotDropExternalStreamingJobs
+ False
+
+
+ DoNotDropExternalTables
+ False
+
+
+ DoNotDropExternalStreams
+ False
+
+
+ DoNotDropFilegroups
+ False
+
+
+ DoNotDropFiles
+ False
+
+
+ DoNotDropFileTables
+ False
+
+
+ DoNotDropFullTextCatalogs
+ False
+
+
+ DoNotDropFullTextStoplists
+ False
+
+
+ DoNotDropTableValuedFunctions
+ False
+
+
+ DoNotDropLinkedServerLogins
+ False
+
+
+ DoNotDropLinkedServers
+ False
+
+
+ DoNotDropLogins
+ False
+
+
+ DoNotDropMessageTypes
+ False
+
+
+ DoNotDropPartitionFunctions
+ False
+
+
+ DoNotDropPartitionSchemes
+ False
+
+
+ DoNotDropPermissions
+ False
+
+
+ DoNotDropQueues
+ False
+
+
+ DoNotDropRemoteServiceBindings
+ False
+
+
+ DoNotDropRoleMembership
+ False
+
+
+ DoNotDropRoutes
+ False
+
+
+ DoNotDropRules
+ False
+
+
+ DoNotDropScalarValuedFunctions
+ False
+
+
+ DoNotDropSearchPropertyLists
+ False
+
+
+ DoNotDropSecurityPolicies
+ False
+
+
+ DoNotDropSequences
+ False
+
+
+ DoNotDropServerAuditSpecifications
+ False
+
+
+ DoNotDropServerRoleMembership
+ False
+
+
+ DoNotDropServerRoles
+ False
+
+
+ DoNotDropServerTriggers
+ False
+
+
+ DoNotDropServices
+ False
+
+
+ DoNotDropSignatures
+ False
+
+
+ DoNotDropStoredProcedures
+ False
+
+
+ DoNotDropSymmetricKeys
+ False
+
+
+ DoNotDropSynonyms
+ False
+
+
+ DoNotDropTables
+ False
+
+
+ DoNotDropUserDefinedDataTypes
+ False
+
+
+ DoNotDropUserDefinedTableTypes
+ False
+
+
+ DoNotDropUsers
+ False
+
+
+ DoNotDropViews
+ False
+
+
+ DoNotDropXmlSchemaCollections
+ False
+
+
+ ExcludeAggregates
+ False
+
+
+ ExcludeApplicationRoles
+ False
+
+
+ ExcludeAssemblies
+ False
+
+
+ ExcludeAsymmetricKeys
+ False
+
+
+ ExcludeAudits
+ True
+
+
+ ExcludeBrokerPriorities
+ False
+
+
+ ExcludeCertificates
+ False
+
+
+ ExcludeClrUserDefinedTypes
+ False
+
+
+ ExcludeColumnEncryptionKeys
+ False
+
+
+ ExcludeColumnMasterKeys
+ False
+
+
+ ExcludeContracts
+ False
+
+
+ ExcludeCredentials
+ True
+
+
+ ExcludeDatabaseScopedCredentials
+ True
+
+
+ ExcludeCryptographicProviders
+ True
+
+
+ ExcludeDatabaseAuditSpecifications
+ True
+
+
+ ExcludeDatabaseRoles
+ False
+
+
+ ExcludeDatabaseTriggers
+ False
+
+
+ ExcludeDefaults
+ False
+
+
+ ExcludeEndpoints
+ True
+
+
+ ExcludeErrorMessages
+ True
+
+
+ ExcludeEventNotifications
+ False
+
+
+ ExcludeExternalDataSources
+ False
+
+
+ ExcludeExternalFileFormats
+ False
+
+
+ ExcludeExternalLanguages
+ False
+
+
+ ExcludeExternalLibraries
+ False
+
+
+ ExcludeExternalStreamingJobs
+ False
+
+
+ ExcludeExternalTables
+ False
+
+
+ ExcludeExternalStreams
+ False
+
+
+ ExcludeEventSessions
+ True
+
+
+ ExcludeFilegroups
+ False
+
+
+ ExcludeFiles
+ True
+
+
+ ExcludeFileTables
+ False
+
+
+ ExcludeFullTextCatalogs
+ False
+
+
+ ExcludeFullTextStoplists
+ False
+
+
+ ExcludeTableValuedFunctions
+ False
+
+
+ ExcludeLinkedServerLogins
+ True
+
+
+ ExcludeLinkedServers
+ True
+
+
+ ExcludeLogins
+ True
+
+
+ ExcludeMessageTypes
+ False
+
+
+ ExcludePartitionFunctions
+ False
+
+
+ ExcludePartitionSchemes
+ False
+
+
+ ExcludeQueues
+ False
+
+
+ ExcludeRemoteServiceBindings
+ False
+
+
+ ExcludeRoutes
+ True
+
+
+ ExcludeRules
+ False
+
+
+ ExcludeScalarValuedFunctions
+ False
+
+
+ ExcludeSearchPropertyLists
+ False
+
+
+ ExcludeSecurityPolicies
+ False
+
+
+ ExcludeSequences
+ False
+
+
+ ExcludeServerAuditSpecifications
+ True
+
+
+ ExcludeServerRoleMembership
+ True
+
+
+ ExcludeServerRoles
+ True
+
+
+ ExcludeServerTriggers
+ True
+
+
+ ExcludeServices
+ False
+
+
+ ExcludeSignatures
+ False
+
+
+ ExcludeStoredProcedures
+ False
+
+
+ ExcludeSymmetricKeys
+ False
+
+
+ ExcludeSynonyms
+ False
+
+
+ ExcludeTables
+ False
+
+
+ ExcludeUserDefinedDataTypes
+ False
+
+
+ ExcludeUserDefinedTableTypes
+ False
+
+
+ ExcludeUsers
+ False
+
+
+ ExcludeViews
+ False
+
+
+ ExcludeXmlSchemaCollections
+ False
+
+
+ AllowExternalLibraryPaths
+ False
+
+
+ AllowExternalLanguagePaths
+ False
+
+
+ Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlServerDdlTrigger
+ ExcludedType
+
+
+ Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlRoute
+ ExcludedType
+
+
+ Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlLinkedServerLogin
+ ExcludedType
+
+
+ Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlEndpoint
+ ExcludedType
+
+
+ Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlErrorMessage
+ ExcludedType
+
+
+ Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlFile
+ ExcludedType
+
+
+ Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlLogin
+ ExcludedType
+
+
+ Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlLinkedServer
+ ExcludedType
+
+
+ Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlCredential
+ ExcludedType
+
+
+ Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlDatabaseCredential
+ ExcludedType
+
+
+ Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlDatabaseEncryptionKey
+ ExcludedType
+
+
+ Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlMasterKey
+ ExcludedType
+
+
+ Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlDatabaseAuditSpecification
+ ExcludedType
+
+
+ Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlServerAudit
+ ExcludedType
+
+
+ Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlServerAuditSpecification
+ ExcludedType
+
+
+ Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlCryptographicProvider
+ ExcludedType
+
+
+ Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlUserDefinedServerRole
+ ExcludedType
+
+
+ Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlEventSession
+ ExcludedType
+
+
+ Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlDatabaseOptions
+ ExcludedType
+
+
+ Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlEventNotification
+ ExcludedType
+
+
+ Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlServerRoleMembership
+ ExcludedType
+
+
+ Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlDatabaseEventSession
+ ExcludedType
+
+
+ Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlAssemblyFile
+ ExcludedType
+
+
+
+
+ 2
+ 100
+ Equals_Objects,Not_Supported_Deploy
+
+
\ No newline at end of file